Image Zoom In/out Sample. This program uses GraphicsFramework library and GP2Y0A21YK sensor. Please use distance sensor in the range of 10-30cm.

Dependencies:   GR-PEACH_video GraphicsFramework R_BSP mbed-rtos mbed

Fork of RGA_HelloWorld by Renesas

About GP2Y0A21YK

GP2Y0A21YK is a distance sensor and can be controlled by using the AnalogIn.
The range of this sensor is 10-80cm.

About wiring

SensorGR-PEACH
White wireA0
Orange wireGND
Black wire5.0V

main.cpp

Committer:
1050186
Date:
2016-05-20
Revision:
6:6cad61e4a4c1
Parent:
5:ac895a9527ab

File content as of revision 6:6cad61e4a4c1:

#include "mbed.h"
#include "rga_func.h"
#include "DisplayBace.h"
#include "rtos.h"

/**** LCD Parameter **********/
#define LCD_DE_MODE            (0)
#define LCD_SYNC_MODE          (1)

#define LCD_DOT_CLOCK          (13.40f)     // 13.4MHz

#define LCD_H_WIDTH            (480u)
#define LCD_H_BACK_PORCH       (43u)
#define LCD_H_FRONT_PORCH      (52u)
#define LCD_H_SYNC_WIDTH       (41u)

#define LCD_V_WIDTH            (272u)
#define LCD_V_BACK_PORCH       (12u)
#define LCD_V_FRONT_PORCH      (2u)
#define LCD_V_SYNC_WIDTH       (10u)

#define LCD_MODE               (LCD_SYNC_MODE)

/*****************************/

/* FRAME BUFFER Parameter */
#define FRAME_BUFFER_BYTE_PER_PIXEL         (2)
#define FRAME_BUFFER_STRIDE                 (((LCD_H_WIDTH * FRAME_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)

DigitalOut  lcd_pwon(P7_15);
DigitalOut  lcd_blon(P8_1);
DigitalOut  touch_reset(P4_0);
PwmOut      lcd_cntrst(P8_15);
DisplayBase Display;
AnalogIn    ain(A0);

static uint8_t user_frame_buffer[FRAME_BUFFER_STRIDE * LCD_V_WIDTH]__attribute((aligned(32)));  /* 32 bytes aligned */
static uint8_t user_frame_buffer2[FRAME_BUFFER_STRIDE * LCD_V_WIDTH]__attribute((aligned(32))); /* 32 bytes aligned */
static frame_buffer_t frame_buffer_info;
static volatile int32_t vsync_count = 0;

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 float get_distance(void) {
    float tmp = 0;
    float data = 0;
    float distance = 0;
    int cnt;

    for (cnt = 0; cnt < 10; cnt++) {
        if (ain == 0) {
            return 0;
        }
        tmp = tmp + ain;
    }
    data = tmp / 10;
    if ((data >= 0.121) && (data <= 0.970)) {
        distance = 26.663 * pow((data * 3.3), -1.25);
    }

    return distance;
}

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

int main(void) {
    /* Create DisplayBase object */
    DisplayBase::graphics_error_t error;
    float distance;

    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_H_WIDTH;
    frame_buffer_info.byte_per_pixel    = FRAME_BUFFER_BYTE_PER_PIXEL;
    frame_buffer_info.stride            = LCD_H_WIDTH * FRAME_BUFFER_BYTE_PER_PIXEL;
    frame_buffer_info.height            = LCD_V_WIDTH;
    frame_buffer_info.pixel_format      = PIXEL_FORMAT_RGB565;

    lcd_pwon = 0;
    lcd_blon = 0;
    touch_reset = 0;
    Thread::wait(100);
 
    lcd_pwon = 1;
    lcd_blon = 1;
    touch_reset = 1;
    Thread::wait(100);

    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
    };
    DisplayBase::rect_t rect;

    lcd_config.lcd_type             = DisplayBase::LCD_TYPE_LVDS;
    lcd_config.intputClock          = 66.67f;
    lcd_config.outputClock          = LCD_DOT_CLOCK;
    lcd_config.lcd_outformat        = DisplayBase::LCD_OUTFORMAT_RGB888;
    lcd_config.lcd_edge             = DisplayBase::EDGE_RISING;
#if(LCD_MODE) //SYNC Mode
    lcd_config.h_toatal_period      = (LCD_H_BACK_PORCH + LCD_H_WIDTH + LCD_H_FRONT_PORCH);
    lcd_config.v_toatal_period      = (LCD_V_BACK_PORCH + LCD_V_WIDTH + LCD_V_FRONT_PORCH);
 
    lcd_config.h_disp_widht         = (LCD_H_WIDTH);
    lcd_config.v_disp_widht         = (LCD_V_WIDTH);
    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_2;
    lcd_config.h_sync_port_polarity = DisplayBase::SIG_POL_INVERTED;
    lcd_config.h_sync_width         = LCD_H_SYNC_WIDTH;
 
    lcd_config.v_sync_port          = DisplayBase::LCD_TCON_PIN_0;
    lcd_config.v_sync_port_polarity = DisplayBase::SIG_POL_INVERTED;
    lcd_config.v_sync_width         = LCD_V_SYNC_WIDTH;
 
    lcd_config.de_port              = DisplayBase::LCD_TCON_PIN_3;
    lcd_config.de_port_polarity     = DisplayBase::SIG_POL_NOT_INVERTED;
#else  //DE Mode
    lcd_config.h_toatal_period      = (LCD_H_WIDTH + 80u);
    lcd_config.v_toatal_period      = (LCD_V_WIDTH);

    lcd_config.h_disp_widht         = (LCD_H_WIDTH);
    lcd_config.v_disp_widht         = (LCD_V_WIDTH);
    lcd_config.h_back_porch         = (68u);
    lcd_config.v_back_porch         = (18u);

    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_INVERTED;
#endif

    /* 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_V_WIDTH;
    rect.hs = 0;
    rect.hw = LCD_H_WIDTH;

    Display.Graphics_Read_Setting(
        DisplayBase::GRAPHICS_LAYER_0,
        (void *)frame_buffer_info.buffer_address[0],
        FRAME_BUFFER_STRIDE,
        DisplayBase::GRAPHICS_FORMAT_RGB565,
        DisplayBase::WR_RD_WRSWA_32_16BIT,
        &rect
    );

    /* Display Top Screen */
    Set_RGAObject(&frame_buffer_info);
    Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0);
    lcd_cntrst.write(1.0);

    int work_height_pos = ZOOM_MAX_NUM;
    while (1) {
        distance = get_distance();
        /* range of use = 10-30[cm] */
        if ((distance >= 10) && (distance <= 30)) {
            work_height_pos = ZOOM_MAX_NUM * (((float32_t)distance - 10) / (float32_t)20);
        }
        /* Draw screen */
        Swap_FrameBuffer(&frame_buffer_info);
        RGA_Func_Zoom(&frame_buffer_info, work_height_pos);
        Update_LCD_Display(&frame_buffer_info);
    }
}