For Seminar
Dependencies: GR-PEACH_video GraphicsFramework R_BSP mbed-rtos mbed
Fork of RGA_HelloWorld by
Diff: main.cpp
- Revision:
- 0:84e4649e7707
- Child:
- 2:c7faef0ef374
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Jan 20 02:35:42 2016 +0000 @@ -0,0 +1,423 @@ +/* +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "mbed.h" +#include "rga_func.h" +#include "DisplayBace.h" +#include "rtos.h" + + +/* LCD Parameter */ +#define LCD_INPUT_CLOCK 66.67f +#define LCD_OUTPUT_CLOCK 33.26f + +#define LCD_PIXEL_WIDTH 800 +#define LCD_PIXEL_HEIGHT 480 +#define LCD_H_BACK_PORCH (128 + 36) +#define LCD_H_FRONT_PORCH 92 +#define LCD_V_BACK_PORCH (35 + 5) +#define LCD_V_FRONT_PORCH 5 + +/* Func Button Image */ +#define XPOS_BUTTON1 50 +#define YPOS_BUTTON1 350 +#define XPOS_BUTTON2 230 +#define YPOS_BUTTON2 YPOS_BUTTON1 +#define XPOS_BUTTON3 410 +#define YPOS_BUTTON3 YPOS_BUTTON1 +#define XPOS_BUTTON4 XPOS_BUTTON1 +#define YPOS_BUTTON4 420 +#define XPOS_BUTTON5 XPOS_BUTTON2 +#define YPOS_BUTTON5 YPOS_BUTTON4 +#define XPOS_BUTTON6 XPOS_BUTTON3 +#define YPOS_BUTTON6 YPOS_BUTTON4 +#define XPOS_BUTTON7 615 +#define YPOS_BUTTON7 YPOS_BUTTON4 +/* Func Button Image Size */ +#define WIDTH_BUTTON 120 +#define HEIGHT_BUTTON 40 +/* Return Button Image */ +#define XPOS_RET_BUTTON 640 +#define YPOS_RET_BUTTON 10 +/* Return Button Image Size */ +#define WIDTH_RET_BUTTON 150 +#define HEIGHT_RET_BUTTON 84 + +/* FRAME BUFFER Parameter */ +#define FRAME_BUFFER_BYTE_PER_PIXEL 2 +#define FRAME_BUFFER_STRIDE (((LCD_PIXEL_WIDTH * FRAME_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u) + +typedef enum { + RGA_FUNC_DRAW_RECTANGLE = 0x00, + RGA_FUNC_DRAW_IMAGE, + RGA_FUNC_DISSOLVE, + RGA_FUNC_SCROLL, + RGA_FUNC_ZOOM, + RGA_FUNC_ROTATION, + RGA_FUNC_ACCELERATE, + RGA_FUNC_MAX_NUM, + RGA_FUNC_RETURN = 0xFE, + RGA_FUNC_NON = 0xFF +}func_code_t; + +DigitalOut lcd_pwon(P7_15); +DigitalOut lcd_blon(P8_1); +PwmOut lcd_cntrst(P8_15); +I2C i2c(I2C_SDA, I2C_SCL); +DisplayBase Display; + +typedef struct { + uint8_t y_h: 3, + reserved: 1, + x_h: 3, + valid: 1; + uint8_t x_l; + uint8_t y_l; + uint8_t z; +} xyz_data_t; + +typedef struct { + uint8_t fingers: 4, + reserved: 4; + uint8_t keys; + xyz_data_t xyz_data; +} stx_report_data_t; + +typedef struct { + uint32_t pic_pos_x; /* X position of the key picture. */ + uint32_t pic_pos_y; /* Y position of the key picture. */ + uint32_t pic_width; /* Width of the key picture. */ + uint32_t pic_height; /* Height of the key picture. */ + func_code_t func_code; /* func code of the key picture. */ +} key_pic_info_t; + +static uint8_t user_frame_buffer[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32))); /* 32 bytes aligned */ +static uint8_t user_frame_buffer2[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32))); /* 32 bytes aligned */ +static frame_buffer_t frame_buffer_info; +static volatile int32_t vsync_count = 0; + +static const key_pic_info_t key_tbl[RGA_FUNC_MAX_NUM] = { + /* X position */ /* Y position */ /* Width size */ /* Height size */ /* Func code */ + { XPOS_BUTTON1, YPOS_BUTTON1, WIDTH_BUTTON, HEIGHT_BUTTON, RGA_FUNC_DRAW_RECTANGLE }, /* RGA Func1 */ + { XPOS_BUTTON2, YPOS_BUTTON2, WIDTH_BUTTON, HEIGHT_BUTTON, RGA_FUNC_DRAW_IMAGE }, /* RGA Func2 */ + { XPOS_BUTTON3, YPOS_BUTTON3, WIDTH_BUTTON, HEIGHT_BUTTON, RGA_FUNC_DISSOLVE }, /* RGA Func3 */ + { XPOS_BUTTON4, YPOS_BUTTON4, WIDTH_BUTTON, HEIGHT_BUTTON, RGA_FUNC_SCROLL }, /* RGA Func4 */ + { XPOS_BUTTON5, YPOS_BUTTON5, WIDTH_BUTTON, HEIGHT_BUTTON, RGA_FUNC_ZOOM }, /* RGA Func5 */ + { XPOS_BUTTON6, YPOS_BUTTON6, WIDTH_BUTTON, HEIGHT_BUTTON, RGA_FUNC_ROTATION }, /* RGA Func6 */ + { XPOS_BUTTON7, YPOS_BUTTON7, WIDTH_BUTTON, HEIGHT_BUTTON, RGA_FUNC_ACCELERATE } /* RGA Func7 */ +}; + +static void IntCallbackFunc_Vsync(DisplayBase::int_type_t int_type) { + /* Interrupt callback function for Vsync interruption */ + if (vsync_count > 0) { + vsync_count--; + } +} + +static void Wait_Vsync(const int32_t wait_count) { + /* Wait for the specified number of times Vsync occurs */ + vsync_count = wait_count; + while (vsync_count > 0) { + /* Do nothing */ + } +} + +static void Init_LCD_Display(uint8_t* disp_buf) { + /* Create DisplayBase object */ + DisplayBase::graphics_error_t error; + DisplayBase::rect_t rect; + 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; + Thread::wait(100); + + lcd_config.lcd_type = DisplayBase::LCD_TYPE_LVDS; + lcd_config.intputClock = LCD_INPUT_CLOCK; + lcd_config.outputClock = LCD_OUTPUT_CLOCK; + lcd_config.lcd_outformat = DisplayBase::LCD_OUTFORMAT_RGB888; + lcd_config.lcd_edge = DisplayBase::EDGE_RISING; + lcd_config.h_toatal_period = (LCD_PIXEL_WIDTH + LCD_H_FRONT_PORCH + LCD_H_BACK_PORCH); + lcd_config.v_toatal_period = (LCD_PIXEL_HEIGHT + LCD_V_FRONT_PORCH + LCD_V_BACK_PORCH); + + lcd_config.h_disp_widht = LCD_PIXEL_WIDTH; + lcd_config.v_disp_widht = LCD_PIXEL_HEIGHT; + lcd_config.h_back_porch = LCD_H_BACK_PORCH; + lcd_config.v_back_porch = LCD_V_BACK_PORCH; + + lcd_config.h_sync_port = DisplayBase::LCD_TCON_PIN_NON; + lcd_config.h_sync_port_polarity = DisplayBase::SIG_POL_NOT_INVERTED; + lcd_config.h_sync_width = 0; + + lcd_config.v_sync_port = DisplayBase::LCD_TCON_PIN_NON; + lcd_config.v_sync_port_polarity = DisplayBase::SIG_POL_NOT_INVERTED; + lcd_config.v_sync_width = 0; + + lcd_config.de_port = DisplayBase::LCD_TCON_PIN_3; + lcd_config.de_port_polarity = DisplayBase::SIG_POL_NOT_INVERTED; + + /* Graphics initialization process */ + error = Display.Graphics_init(&lcd_config); + if (error != DisplayBase::GRAPHICS_OK) { + printf("Line %d, error %d\n", __LINE__, error); + while (1); + } + + /* Interrupt callback function setting (Vsync signal output from scaler 0) */ + error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_LO_VSYNC, 0, IntCallbackFunc_Vsync); + if (error != DisplayBase::GRAPHICS_OK) { + printf("Line %d, error %d\n", __LINE__, error); + while (1); + } + + Display.Graphics_Lvds_Port_Init(lvds_pin, 8); + 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 *)disp_buf, + FRAME_BUFFER_STRIDE, + DisplayBase::GRAPHICS_FORMAT_RGB565, + DisplayBase::WR_RD_WRSWA_32_16BIT, + &rect + ); +} + +static void Start_LCD_Display(void) { + Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0); + + lcd_cntrst.write(1.0); +} + +static void Update_LCD_Display(uint8_t* disp_buf) { + Display.Graphics_Read_Change(DisplayBase::GRAPHICS_LAYER_0, (void *)disp_buf); + Wait_Vsync(1); +} + +static int Get_Coordinates(uint8_t *count, uint32_t *x0, uint32_t *y0) { + char buf[6]; + stx_report_data_t *pdata; + int ret = -1; + *count = 0; // Set point detected count to 0 + + if (i2c.read((0x55 << 1), buf, sizeof(buf)) == 0) { + pdata = (stx_report_data_t *)buf; + if (pdata->fingers) { + if (pdata->xyz_data.valid) { + *x0 = (pdata->xyz_data.x_h << 8) | pdata->xyz_data.x_l; + *y0 = (pdata->xyz_data.y_h << 8) | pdata->xyz_data.y_l; + (*count)++; + } + } + ret = 0; + } + + return ret; +} + +static func_code_t Scan_FuncCode(uint32_t pos_x, const uint32_t pos_y) { + int func_cnt; + func_code_t ret = RGA_FUNC_NON; + + for (func_cnt = 0; ((func_cnt < RGA_FUNC_MAX_NUM) && (ret == RGA_FUNC_NON)); func_cnt++) { + /* Check the range of the X position */ + if ((pos_x >= key_tbl[func_cnt].pic_pos_x) && (pos_x <= (key_tbl[func_cnt].pic_pos_x + key_tbl[func_cnt].pic_width))) { + /* Check the range of the Y position */ + if ((pos_y >= key_tbl[func_cnt].pic_pos_y) && (pos_y <= (key_tbl[func_cnt].pic_pos_y + key_tbl[func_cnt].pic_height))) { + /* Decide the func code. */ + ret = key_tbl[func_cnt].func_code; + } + } + } + + return ret; +} + +static func_code_t Scan_ReturnCode(uint32_t pos_x, const uint32_t pos_y) { + func_code_t ret = RGA_FUNC_NON; + + /* Check the range of the X position */ + if ((pos_x >= XPOS_RET_BUTTON) && (pos_x <= (XPOS_RET_BUTTON + WIDTH_RET_BUTTON))) { + /* Check the range of the Y position */ + if ((pos_y >= YPOS_RET_BUTTON) && (pos_y <= (YPOS_RET_BUTTON + HEIGHT_RET_BUTTON))) { + /* Decide the func code. */ + ret = RGA_FUNC_RETURN; + } + } + + return ret; +} + +static void Swap_FrameBuffer(frame_buffer_t * frmbuf_info) { + if (frmbuf_info->draw_buffer_index == 1) { + frmbuf_info->draw_buffer_index = 0; + } else { + frmbuf_info->draw_buffer_index = 1; + } +} + +static void Exe_RGA_Func(int func_name, frame_buffer_t* frmbuf_info) { + uint8_t* disp_buf; + + switch (func_name) { + case RGA_FUNC_DRAW_RECTANGLE: + /* Swap frame buffer */ + Swap_FrameBuffer(frmbuf_info); + disp_buf = frmbuf_info->buffer_address[frmbuf_info->draw_buffer_index]; + RGA_Func_DrawRectangle(frmbuf_info); + Update_LCD_Display(disp_buf); + break; + case RGA_FUNC_DRAW_IMAGE: + /* Swap frame buffer */ + Swap_FrameBuffer(frmbuf_info); + disp_buf = frmbuf_info->buffer_address[frmbuf_info->draw_buffer_index]; + RGA_Func_DrawImage(frmbuf_info); + Update_LCD_Display(disp_buf); + break; + case RGA_FUNC_DISSOLVE: + int diss_frame_num; + float32_t work_alpha; + for (diss_frame_num = 0; diss_frame_num < DISSOLVE_MAX_NUM; diss_frame_num += 1) { + /* Swap frame buffer */ + Swap_FrameBuffer(frmbuf_info); + disp_buf = frmbuf_info->buffer_address[frmbuf_info->draw_buffer_index]; + work_alpha = diss_frame_num / (float32_t)(DISSOLVE_MAX_NUM - 1); + RGA_Func_Dissolve(frmbuf_info, work_alpha); + Update_LCD_Display(disp_buf); + } + break; + case RGA_FUNC_SCROLL: + int work_width_pos; + for (work_width_pos = 0; work_width_pos < SCROLL_MAX_NUM; work_width_pos++) { + /* Swap frame buffer */ + Swap_FrameBuffer(frmbuf_info); + disp_buf = frmbuf_info->buffer_address[frmbuf_info->draw_buffer_index]; + RGA_Func_Scroll(frmbuf_info, work_width_pos); + Update_LCD_Display(disp_buf); + } + break; + case RGA_FUNC_ZOOM: + int work_height_pos; + for (work_height_pos = 0; work_height_pos <= ZOOM_MAX_NUM; work_height_pos++) { + /* Swap frame buffer */ + Swap_FrameBuffer(frmbuf_info); + disp_buf = frmbuf_info->buffer_address[frmbuf_info->draw_buffer_index]; + RGA_Func_Zoom(frmbuf_info, work_height_pos); + Update_LCD_Display(disp_buf); + } + break; + case RGA_FUNC_ROTATION: + graphics_matrix_float_t work_angle; + for (work_angle = 0; work_angle <= ROTATION_MAX_NUM; work_angle++) { + /* Swap frame buffer */ + Swap_FrameBuffer(frmbuf_info); + disp_buf = frmbuf_info->buffer_address[frmbuf_info->draw_buffer_index]; + RGA_Func_Rotation(frmbuf_info, work_angle); + Update_LCD_Display(disp_buf); + } + break; + case RGA_FUNC_ACCELERATE: + int acce_frame_num; + float32_t work_relative_pos; + Get_AnimationTiming("ease"); + for (acce_frame_num = 0; acce_frame_num <= ACCELERATE_MAX_NUM; acce_frame_num++) { + /* Swap frame buffer */ + Swap_FrameBuffer(frmbuf_info); + disp_buf = frmbuf_info->buffer_address[frmbuf_info->draw_buffer_index]; + work_relative_pos = acce_frame_num / (float32_t)ACCELERATE_MAX_NUM; + RGA_Func_Accelerate(frmbuf_info, work_relative_pos); + Update_LCD_Display(disp_buf); + } + break; + default : + /* Do nothing */ + break; + } +} + +int main(void) { + func_code_t func_code; + frame_buffer_t* work_frm_buf; + uint8_t* disp_buffer; + uint8_t touch_num = 0; + uint32_t pos_x0 = 0; + uint32_t pos_y0 = 0; + + memset(user_frame_buffer, 0, sizeof(user_frame_buffer)); + memset(user_frame_buffer2, 0, sizeof(user_frame_buffer2)); + frame_buffer_info.buffer_address[0] = user_frame_buffer; + frame_buffer_info.buffer_address[1] = user_frame_buffer2; + frame_buffer_info.buffer_count = 2; + frame_buffer_info.show_buffer_index = 0; + frame_buffer_info.draw_buffer_index = 0; + frame_buffer_info.width = LCD_PIXEL_WIDTH; + frame_buffer_info.byte_per_pixel = FRAME_BUFFER_BYTE_PER_PIXEL; + frame_buffer_info.stride = LCD_PIXEL_WIDTH * FRAME_BUFFER_BYTE_PER_PIXEL; + frame_buffer_info.height = LCD_PIXEL_HEIGHT; + frame_buffer_info.pixel_format = PIXEL_FORMAT_RGB565; + disp_buffer = frame_buffer_info.buffer_address[0]; + Init_LCD_Display(disp_buffer); + + /* Display Top Screen */ + work_frm_buf = &frame_buffer_info; + Set_RGAObject(work_frm_buf); + RGA_Func_DrawTopScreen(work_frm_buf); + Start_LCD_Display(); + + while (1) { + Get_Coordinates(&touch_num, &pos_x0, &pos_y0); + if (touch_num != 0) { + func_code = Scan_FuncCode(pos_x0, pos_y0); + if (func_code != RGA_FUNC_NON) { + /* Execute RGA functions */ + Exe_RGA_Func(func_code, work_frm_buf); + Thread::wait(1000); + /* Display Return Button */ + disp_buffer = work_frm_buf->buffer_address[work_frm_buf->draw_buffer_index]; + RGA_Func_DrawReturnButton(work_frm_buf); + Update_LCD_Display(disp_buffer); + /* Wait until Return Code is pressed */ + while (func_code != RGA_FUNC_RETURN) { + Get_Coordinates(&touch_num, &pos_x0, &pos_y0); + if (touch_num != 0) { + func_code = Scan_ReturnCode(pos_x0, pos_y0); + } + Thread::wait(100); + } + /* Return Top Screen */ + Swap_FrameBuffer(work_frm_buf); + disp_buffer = work_frm_buf->buffer_address[work_frm_buf->draw_buffer_index]; + RGA_Func_DrawTopScreen(work_frm_buf); + Update_LCD_Display(disp_buffer); + } + } + Thread::wait(100); + } +}