Daiki Kato / Mbed 2 deprecated GR-PEACH_Digital_Signage_display_shield

Dependencies:   GR-PEACH_video GraphicsFramework R_BSP SDFileSystem_tmp mbed-rtos mbed

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;
+        }
+    }
+}