MY TRAIAL (1)

Dependencies:   FATFileSystem GR-PEACH_video GraphicsFramework LCD_shield_config R_BSP mbed-rtos mbed

Fork of GR-PEACH_NTSC_in_2ch_MOD_try by Hirofumi Inomata

I put an OVERVIEW in the blow URL. https://developer.mbed.org/users/digiponta/notebook/my-trial-ar--vr-2-eyes-display-goes-by-a-gr-peach/

main.cpp

Committer:
digiponta
Date:
2016-09-14
Revision:
6:3cb7758c3f17
Parent:
5:f6df6a4c32a7
Child:
7:2fb4359e5ea6

File content as of revision 6:3cb7758c3f17:

#include "mbed.h"
#include "SDFileSystem_GR_PEACH.h"
#include "FATFileSystem.h"
#include "JPEG_Converter.h"
#include "DisplayBace.h"
#include "rtos.h"

DigitalOut led1(LED1);
Serial pc(USBTX, USBRX);
// SDFileSystem sd(P8_5, P8_6, P8_3, P8_4, "sd");
SDFileSystem_GR_PEACH sd( "sd" );

FILE *rd_fp = NULL;
FILE *wr_fp = NULL;
long fsize = 0;
DIR *dir;
struct dirent *dp;

DigitalIn   sw0(USER_BUTTON0);
// DigitalIn   sw1(P6_1);
DigitalIn   sw2(P4_0);
DigitalIn   sw3(P2_13);

int prev_sw0 = 1;
// int prev_sw1 = 1;
int prev_sw2 = 1;
int prev_sw3 = 1;
int mode = 0;
char fname[64];

unsigned int imgCnt = 0;
unsigned int viewCnt = 0;


#define VIDEO_YCBCR422         (0)
#define VIDEO_RGB888           (1)
#define VIDEO_RGB565           (2)

/**** User Selection *********/
/** Camera setting **/
#define VIDEO_INPUT_FORMAT     (VIDEO_YCBCR422)    /* Select  VIDEO_YCBCR422 or VIDEO_RGB888 or VIDEO_RGB565        */
#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 **/
/* 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

/*! 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 */
#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)

static DisplayBase Display;
static DigitalOut  lcd_pwon(P7_15);
static DigitalOut  lcd_blon(P8_1);
static PwmOut      lcd_cntrst(P8_15);
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];
static uint8_t user_frame_buffer1[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
#pragma data_alignment=4
#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)));
#endif
static bool graphics_init_end = false;

/****** LCD ******/
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;
}

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

static volatile int32_t vfield_count_0 = 1;
static volatile int32_t vfield_count_1 = 1;

/** Video and Grapics (GRAPHICS_LAYER_0) parameter **/
/* video input */
#define VIDEO_INPUT_CH_0       (DisplayBase::VIDEO_INPUT_CHANNEL_0)
#define VIDEO_INPUT_CH_1       (DisplayBase::VIDEO_INPUT_CHANNEL_1)
#define VIDEO_INT_TYPE_0       (DisplayBase::INT_TYPE_S0_VFIELD)
#define VIDEO_INT_TYPE_1       (DisplayBase::INT_TYPE_S1_VFIELD)

static void IntCallbackFunc_Vfield_0(DisplayBase::int_type_t int_type) {
    DisplayBase::graphics_error_t error;

    /* Interrupt callback function */
    if (vfield_count_0 == 0) {
        vfield_count_0 = 1;
        error = Display.Video_Stop( DisplayBase::VIDEO_INPUT_CHANNEL_0 );
        if (error != DisplayBase::GRAPHICS_OK) {
            printf("Line %d, error %d\n", __LINE__, error);
            mbed_die();
        }
    } else {
        ;
    }
}

static void IntCallbackFunc_Vfield_1(DisplayBase::int_type_t int_type) {
    DisplayBase::graphics_error_t error;

    /* Interrupt callback function */
    if (vfield_count_1 == 0) {
        vfield_count_1 = 1;
        error = Display.Video_Stop( DisplayBase::VIDEO_INPUT_CHANNEL_1 );
        if (error != DisplayBase::GRAPHICS_OK) {
            printf("Line %d, error %d\n", __LINE__, error);
            mbed_die();
        }
    } else {
        ;
    }
}

/****** Video ******/
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;
    }

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

    /* Interrupt callback function setting (Field end signal for recording function in scaler 0) */
    error = Display.Graphics_Irq_Handler_Set(VIDEO_INT_TYPE_0, 0, IntCallbackFunc_Vfield_0);
    if (error != DisplayBase::GRAPHICS_OK) {
        printf("Line %d, error %d\n", __LINE__, error);
        mbed_die();
    }
    /* Interrupt callback function setting (Field end signal for recording function in scaler 0) */
    error = Display.Graphics_Irq_Handler_Set(VIDEO_INT_TYPE_1, 0, IntCallbackFunc_Vfield_1);
    if (error != DisplayBase::GRAPHICS_OK) {
        printf("Line %d, error %d\n", __LINE__, error);
        mbed_die();
    }
}

static void Start_Video(DisplayBase::video_input_channel_t ch, uint8_t * p_frame_buffer,
 uint16_t pos_x, uint16_t pos_y, uint16_t width, uint16_t height) {
    DisplayBase::graphics_error_t error;
    uint8_t * p_buf;

    p_buf = p_frame_buffer + (FRAME_BUFFER_BYTE_PER_PIXEL * pos_x) + (FRAME_BUFFER_STRIDE * pos_y);

    /* Video capture setting (progressive form fixed) */
    error = Display.Video_Write_Setting(
                ch,
                COL_SYS,
                p_buf,
                FRAME_BUFFER_STRIDE,
                VIDEO_FORMAT,
                WR_RD_WRSWA,
                (height & ~7u),      /* A multiple of 8 */
                (width  & ~15u)      /* A multiple of 16 */
            );
    if (error != DisplayBase::GRAPHICS_OK) {
        printf("Line %d, error %d\n", __LINE__, error);
        mbed_die();
    }

    /* Video write process start */
    error = Display.Video_Start(ch);
    if (error != DisplayBase::GRAPHICS_OK) {
        printf("Line %d, error %d\n", __LINE__, error);
        mbed_die();
    }

    /* Video write process stop */
    error = Display.Video_Stop(ch);
    if (error != DisplayBase::GRAPHICS_OK) {
        printf("Line %d, error %d\n", __LINE__, error);
        mbed_die();
    }

    /* Video write process start */
    error = Display.Video_Start(ch);
    if (error != DisplayBase::GRAPHICS_OK) {
        printf("Line %d, error %d\n", __LINE__, error);
        mbed_die();
    }
}

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

// キャッシュインバリデート関数を追加
static void dcache_invalid(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 invalid */
    for (addr = start_addr; addr < end_addr; addr += 0x20) {
        __v7_inv_dcache_mva((void *)addr);
    }
}

/****** main ******/
int main(void) {
    JPEG_Converter  decoder;
    JPEG_Converter::bitmap_buff_info_t  aBitmapData;
    DisplayBase::graphics_error_t error;
    size_t EncodeSize;

    while( !sd.connected() ) {
         Thread::wait(500);
    }
    
    /* Initialization of LCD */
    Init_LCD_Display();    /* When using LCD, please call before than Init_Video(). */

    /* Initialization of Video */
    Init_Video();

    /* Initialization memory */
#if VIDEO_INPUT_FORMAT == VIDEO_YCBCR422
    for (int i = 0; i < sizeof(user_frame_buffer0); i += 2) {
        user_frame_buffer0[i + 0] = 0x10;
        user_frame_buffer0[i + 1] = 0x80;
    }
#else
    memset(user_frame_buffer0, 0, sizeof(user_frame_buffer0));
    memset(user_frame_buffer1, 0, sizeof(user_frame_buffer1));
#endif
    dcache_clean(user_frame_buffer0, sizeof(user_frame_buffer0));
    dcache_clean(user_frame_buffer1, sizeof(user_frame_buffer1));

    /* Start of Video ch0 */
    Start_Video(
        DisplayBase::VIDEO_INPUT_CHANNEL_0,   /* Video input channe */
        user_frame_buffer0,                   /* Output buffer */
        0,                                    /* The x coordinate of the upper-left corner */
        0,                                    /* The y coordinate of the upper-left corner */
        (LCD_PIXEL_WIDTH / 2),                /* width  (A multiple of 16) */
        LCD_PIXEL_HEIGHT                      /* height (A multiple of 8) */
    );

    /* Start of Video ch1 */
    Start_Video(
        DisplayBase::VIDEO_INPUT_CHANNEL_1,   /* Video input channe */
        user_frame_buffer0,                   /* Output buffer */
        (LCD_PIXEL_WIDTH / 2),                /* The x coordinate of the upper-left corner */
        0,                                    /* The y coordinate of the upper-left corner */
        (LCD_PIXEL_WIDTH / 2),                /* width  (A multiple of 16) */
        LCD_PIXEL_HEIGHT                      /* height (A multiple of 8) */
    );

    /* Start of LCD */
    Start_LCD_Display(&user_frame_buffer0[0]);

    /* Backlight on */
    Thread::wait(200);
    lcd_cntrst.write(1.0);


    dir = opendir( "/sd" );
    for ( imgCnt=0; ; imgCnt++) {
        dp = readdir( dir );
        if ( dp == NULL) break;
    }
    closedir( dir );

    while (1) {

        led_blue = !led_blue;
        Thread::wait(100);

        if ((mode == 0) && (prev_sw0 != 0) && (sw0 == 0)) 
        {
            
#if 1
            for ( vfield_count_0=0; vfield_count_0 == 0; ) {
            }

            for ( vfield_count_1=0; vfield_count_1 == 0; ) {
            }
#if 1

            Thread::wait(500);
           
            //YCbCr setting 
            aBitmapData.width           = LCD_PIXEL_WIDTH;
            aBitmapData.height          = LCD_PIXEL_HEIGHT;
            aBitmapData.format          = JPEG_Converter::WR_RD_YCbCr422;   //YCbCr[0] & ARGB8888[1] is 4byte, not RGB565[2] is 2byte
            aBitmapData.buffer_address  = (void *)user_frame_buffer0;
            pc.printf("File encode start\n");
            // JPEG_Converter
            
            dcache_invalid(user_frame_buffer1, sizeof(user_frame_buffer1));
            if (decoder.encode(&aBitmapData, user_frame_buffer1, &EncodeSize) == JPEG_Converter::JPEG_CONV_OK) {
                pc.printf("File encode done %dbyte, %d\n", EncodeSize, imgCnt );
                                
                pc.printf("File write start\n");
                sprintf( fname, "/sd/img_%04d.jpg", imgCnt++ );
                wr_fp = fopen( fname, "w");
                for( long i=0; i < EncodeSize;i++) {
                    putc( user_frame_buffer1[i], wr_fp );
                }
                fflush(wr_fp);
                fclose(wr_fp);
                pc.printf("File write done\n");
                led1 = 0;
            } else {
                pc.printf("Error:JCU encode error\n");
                led1 = 0;
            }
#endif

            Thread::wait(500); 
            // NVIC_SystemReset();          
        
            /* Video write process start */
            error = Display.Video_Start( DisplayBase::VIDEO_INPUT_CHANNEL_0 );
            if (error != DisplayBase::GRAPHICS_OK) {
                printf("Line %d, error %d\n", __LINE__, error);
                mbed_die();
            }           
            /* Video write process start */
            error = Display.Video_Start( DisplayBase::VIDEO_INPUT_CHANNEL_1 );
            if (error != DisplayBase::GRAPHICS_OK) {
                printf("Line %d, error %d\n", __LINE__, error);
                mbed_die();
            }           
#endif
        }

        if (((mode == 0) || (mode == 1)) && (prev_sw2 != 0) && (sw2 == 0)) {
             if ( mode == 0 ){
                 
                 /* Video write process stop */
                error = Display.Video_Stop( DisplayBase::VIDEO_INPUT_CHANNEL_0 );
                if (error != DisplayBase::GRAPHICS_OK) {
                    printf("Line %d, error %d\n", __LINE__, error);
                    mbed_die();
                }
                error = Display.Video_Stop( DisplayBase::VIDEO_INPUT_CHANNEL_1 );
                if (error != DisplayBase::GRAPHICS_OK) {
                    printf("Line %d, error %d\n", __LINE__, error);
                    mbed_die();
                }
            }
            
            
            sprintf( fname, "/sd/img_%04d.jpg", viewCnt++ );
            if ( viewCnt >= imgCnt ) viewCnt = 0;
            pc.printf("File read start %s v=%d, i=%d\n", fname, viewCnt, imgCnt );

            // dcache_invalid(user_frame_buffer1, sizeof(user_frame_buffer1));
            // dcache_invalid(user_frame_buffer0, sizeof(user_frame_buffer0));
           
            rd_fp = fopen( fname, "r" );
            if (rd_fp == NULL ) {
                pc.printf("can't open the file\n" ); 
                mode = 1;
                continue;
            }
            fseek( rd_fp, 0, SEEK_SET );
#if 0
            fsize = ftell( rd_fp );
             if (fsize == 0) {
                pc.printf("fsize = 0 error\n" ); 
                mode = 1;
                continue;                
            }
            pc.printf("fsize = %d\n", fsize );
            fseek( rd_fp, 0, SEEK_SET );
            for( long i=0; i < fsize ;i++) {
                char cc = getc( rd_fp );
                // if ( cc == EOF ) break;
                user_frame_buffer1[i] = (unsigned char)cc;
            }
#else
            size_t len = fread(user_frame_buffer1, sizeof(char), sizeof(user_frame_buffer1), rd_fp);  
            pc.printf( "len = %d\n", len );
#endif 
            fclose(rd_fp);
            pc.printf("File read done\n");


             //YCbCr setting
            aBitmapData.width           = LCD_PIXEL_WIDTH;
            aBitmapData.height          = LCD_PIXEL_HEIGHT;
            aBitmapData.format          = JPEG_Converter::WR_RD_YCbCr422;   //YCbCr[0] & ARGB8888[1] is 4byte, not RGB565[2] is 2byte
            aBitmapData.buffer_address  = (void *)user_frame_buffer0;
            pc.printf("File decode start\n");
            // JPEG_Converter
            if (decoder.decode((void *)user_frame_buffer1, &aBitmapData) == JPEG_Converter::JPEG_CONV_OK) {
                pc.printf("File decode done %dbyte\n", (LCD_PIXEL_WIDTH * LCD_PIXEL_HEIGHT * 4));
                led1 = 0;
            } else {
                pc.printf("Error:JCU decode error\n");
                led1 = 0;
            }
 
            mode = 1;
        }        
        
        if ( (mode == 1) && (prev_sw3 != 0) && (sw3 == 0)) {

            /* Video write process start */
            error = Display.Video_Start( DisplayBase::VIDEO_INPUT_CHANNEL_0 );
            if (error != DisplayBase::GRAPHICS_OK) {
                printf("Line %d, error %d\n", __LINE__, error);
                mbed_die();
            }           
            /* Video write process start */
            error = Display.Video_Start( DisplayBase::VIDEO_INPUT_CHANNEL_1 );
            if (error != DisplayBase::GRAPHICS_OK) {
                printf("Line %d, error %d\n", __LINE__, error);
                mbed_die();
            }           
        
            mode = 0; // 
        }        



        prev_sw0 = sw0;
 //     prev_sw1 = sw1;
        prev_sw2 = sw2;
        prev_sw3 = sw3;
    }
}