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: GR-PEACH_video GraphicsFramework R_BSP SDFileSystem_tmp mbed-rtos mbed
Diff: main.cpp
- Revision:
- 0:8970afa15acc
- Child:
- 1:2f9f102b2b4c
diff -r 000000000000 -r 8970afa15acc main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue May 24 06:35:47 2016 +0000 @@ -0,0 +1,345 @@ +/* +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 "DisplayBace.h" +#include "RGA.h" +#include "rtos.h" +#include "SDFileSystem.h" + +#define SVGA (0u) /* 800 x 600 */ +#define XGA (1u) /* 1024 x 768 */ +#define WXGA (2u) /* 1280 x 800 */ + +/**** User Selection *********/ +#define WAIT_TIME (8000) +#define DISSOLVE_STEP_NUM (16) /* minimum 1 */ +#define SCROLL_STEP_NUM (8) /* minimum 1 */ +#define SCROLL_DIRECTION (-1) /* Select 1(left to right) or -1(right to left) */ +#define LCD_SIZE WXGA /* Select SVGA, XGA or WXGA */ +#define MAX_JPEG_SIZE (1024 * 300) +/*****************************/ + +#define FILE_NAME_LEN (64) +#define TEXT_SIZE (64 + 1) //null-terminated +#define FLD_PATH "/sd/" + +/* LCD Parameter */ +#define LCD_INPUT_CLOCK (66.67f) +#if ( LCD_SIZE == SVGA ) +#define LCD_OUTPUT_CLOCK (40.0f) +#define LCD_PIXEL_WIDTH (800u) +#define LCD_PIXEL_HEIGHT (600u) +#define LCD_H_BACK_PORCH (88u) +#define LCD_H_FRONT_PORCH (40u) +#define LCD_H_SYNC_WIDTH (128u) +#define LCD_V_BACK_PORCH (23u) +#define LCD_V_FRONT_PORCH (1u) +#define LCD_V_SYNC_WIDTH (4u) +#elif ( LCD_SIZE == XGA ) +#define LCD_OUTPUT_CLOCK (65.00325f) +#define LCD_PIXEL_WIDTH (1024u) +#define LCD_PIXEL_HEIGHT (768u) +#define LCD_H_BACK_PORCH (160u) +#define LCD_H_FRONT_PORCH (24u) +#define LCD_H_SYNC_WIDTH (136u) +#define LCD_V_BACK_PORCH (29u) +#define LCD_V_FRONT_PORCH (3u) +#define LCD_V_SYNC_WIDTH (6u) +#elif ( LCD_SIZE == WXGA ) +#define LCD_OUTPUT_CLOCK (83.51112f) +#define LCD_PIXEL_WIDTH (1280u) +#define LCD_PIXEL_HEIGHT (800u) +#define LCD_H_BACK_PORCH (200u) +#define LCD_H_FRONT_PORCH (64u) +#define LCD_H_SYNC_WIDTH (136u) +#define LCD_V_BACK_PORCH (24u) +#define LCD_V_FRONT_PORCH (1u) +#define LCD_V_SYNC_WIDTH (3u) +#endif + +/* FRAME BUFFER Parameter */ +#define FRAME_BUFFER_BYTE_PER_PIXEL (2) +#define FRAME_BUFFER_STRIDE (((LCD_PIXEL_WIDTH * FRAME_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u) + +DigitalIn button(USER_BUTTON0); +I2C i2c(I2C_SDA, I2C_SCL); +DisplayBase Display; +Canvas2D_ContextClass canvas2d; + +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; + +#if defined(__ICCARM__) +#pragma data_alignment=8 +static uint8_t JpegBuffer[2][MAX_JPEG_SIZE]@ ".mirrorram"; //8 bytes aligned!; +#pragma data_alignment=4 +#else +static uint8_t JpegBuffer[2][MAX_JPEG_SIZE]__attribute((section("NC_BSS"),aligned(8))); //8 bytes aligned!; +#endif + +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 lcd_pin[28] = { + /* data pin */ + P11_15, P11_14, P11_13, P11_12, P5_7, P5_6, P5_5, P5_4, P5_3, P5_2, P5_1, P5_0, + P4_7, P4_6, P4_5, P4_4, P10_12, P10_13, P10_14, P10_15, P3_15, P3_14, P3_13, + P3_12, P3_11, P3_10, P3_9, P3_8 + }; + + Thread::wait(100); + + lcd_config.lcd_type = DisplayBase::LCD_TYPE_PARALLEL_RGB; + 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_1; + lcd_config.h_sync_port_polarity = DisplayBase::SIG_POL_NOT_INVERTED; + lcd_config.h_sync_width = LCD_H_SYNC_WIDTH; + + lcd_config.v_sync_port = DisplayBase::LCD_TCON_PIN_2; + lcd_config.v_sync_port_polarity = DisplayBase::SIG_POL_NOT_INVERTED; + lcd_config.v_sync_width = LCD_V_SYNC_WIDTH; + + lcd_config.de_port = DisplayBase::LCD_TCON_PIN_0; + 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_Lcd_Port_Init(lcd_pin, 28); + 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); +} + +static void Update_LCD_Display(frame_buffer_t * frmbuf_info) { + Display.Graphics_Read_Change(DisplayBase::GRAPHICS_LAYER_0, + (void *)frmbuf_info->buffer_address[frmbuf_info->draw_buffer_index]); + Wait_Vsync(1); +} + +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 draw_image(frame_buffer_t* frmbuf_info, const graphics_image_t* image_new) { + Swap_FrameBuffer(frmbuf_info); + /* Clear */ + canvas2d.clearRect(0, 0, frmbuf_info->width, frmbuf_info->height); + /* Draw a image */ + canvas2d.globalAlpha = 1.0f; + canvas2d.drawImage((const graphics_image_t*)image_new, 0, 0, frmbuf_info->width, frmbuf_info->height); + R_OSPL_CLEAR_ERROR(); + /* Complete drawing */ + R_GRAPHICS_Finish(canvas2d.c_LanguageContext); + Update_LCD_Display(frmbuf_info); +} + +static void draw_image_scroll(frame_buffer_t* frmbuf_info, const graphics_image_t* image_last, + const graphics_image_t* image_new, float32_t scroll) { + Swap_FrameBuffer(frmbuf_info); + /* Clear */ + canvas2d.clearRect(0, 0, frmbuf_info->width, frmbuf_info->height); + /* Draw a image */ + canvas2d.globalAlpha = 1.0f; + canvas2d.drawImage((const graphics_image_t*)image_last, + (int_t)(frmbuf_info->width * scroll) * SCROLL_DIRECTION, 0, + frmbuf_info->width, frmbuf_info->height); + R_OSPL_CLEAR_ERROR(); + canvas2d.globalAlpha = 1.0f; + canvas2d.drawImage((const graphics_image_t*)image_new, + ((int_t)(frmbuf_info->width * scroll) - frmbuf_info->width) * SCROLL_DIRECTION, 0, + frmbuf_info->width, frmbuf_info->height); + R_OSPL_CLEAR_ERROR(); + /* Complete drawing */ + R_GRAPHICS_Finish(canvas2d.c_LanguageContext); + Update_LCD_Display(frmbuf_info); +} + +static void draw_image_dissolve(frame_buffer_t* frmbuf_info, const graphics_image_t* image_last, + const graphics_image_t* image_new, float32_t alpha) { + Swap_FrameBuffer(frmbuf_info); + /* Clear */ + canvas2d.clearRect(0, 0, frmbuf_info->width, frmbuf_info->height); + /* Draw a image */ + canvas2d.globalAlpha = 1.0f - alpha; + canvas2d.drawImage((const graphics_image_t*)image_last, 0, 0, frmbuf_info->width, frmbuf_info->height); + R_OSPL_CLEAR_ERROR(); + canvas2d.globalAlpha = alpha; + canvas2d.drawImage((const graphics_image_t*)image_new, 0, 0, frmbuf_info->width, frmbuf_info->height); + R_OSPL_CLEAR_ERROR(); + /* Complete drawing */ + R_GRAPHICS_Finish(canvas2d.c_LanguageContext); + Update_LCD_Display(frmbuf_info); +} + +int main(void) { + errnum_t err; + Canvas2D_ContextConfigClass config; + + 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; + Init_LCD_Display(frame_buffer_info.buffer_address[0]); + + config.frame_buffer = &frame_buffer_info; + canvas2d = R_RGA_New_Canvas2D_ContextClass(config); + err = R_OSPL_GetErrNum(); + if (err != 0) { + printf("Line %d, error %d\n", __LINE__, err); + while (1); + } + Start_LCD_Display(); + + SDFileSystem sd(P8_5, P8_6, P8_3, P8_4, "sd"); + FILE * fp = NULL; + DIR * d = NULL; + char file_path[sizeof(FLD_PATH) + FILE_NAME_LEN]; + int jpeg_toggle = 0; + bool first_view = true; + size_t ret; + + while (1) { + // file search + if (d == NULL) { + d = opendir(FLD_PATH); + } + struct dirent * p; + while ((p = readdir(d)) != NULL) { + size_t len = strlen(p->d_name); + if ((len > 4) && (len < FILE_NAME_LEN) + && (strncasecmp(&p->d_name[len - 4], ".jpg", 4) == 0)) { + strcpy(file_path, FLD_PATH); + strcat(file_path, p->d_name); + fp = fopen(file_path, "r"); + ret = fread(&JpegBuffer[jpeg_toggle], sizeof(char), MAX_JPEG_SIZE, fp); + fclose(fp); + if (ret < MAX_JPEG_SIZE) { + if (first_view != false) { + // Effect NONE + first_view = false; + draw_image(&frame_buffer_info, (const graphics_image_t*)&JpegBuffer[jpeg_toggle]); + } else { + bool key_press = false; + // Wait timeout or key press + for (int i = 0; i < WAIT_TIME; i += 100) { + if (button == 0) { + key_press = true; + break; + } + Thread::wait(100); + } + if (key_press == false) { + // Effect DISSOLVE + for (int i = 1; i <= DISSOLVE_STEP_NUM; i++) { + draw_image_dissolve(&frame_buffer_info, + (const graphics_image_t*)&JpegBuffer[!jpeg_toggle], + (const graphics_image_t*)&JpegBuffer[jpeg_toggle], + (float32_t)i / (float32_t)DISSOLVE_STEP_NUM); + } + } else { + // Effect SCROLL + for (int i = 1; i <= SCROLL_STEP_NUM; i++) { + draw_image_scroll(&frame_buffer_info, + (const graphics_image_t*)&JpegBuffer[!jpeg_toggle], + (const graphics_image_t*)&JpegBuffer[jpeg_toggle], + (float32_t)i / (float32_t)SCROLL_STEP_NUM); + } + } + } + jpeg_toggle = !jpeg_toggle; + } + break; + } + } + if (p == NULL) { + closedir(d); + d = NULL; + } + } +}