Camera in sample for GR-PEACH

Dependencies:   GR-PEACH_video USBHost_custom

Video Links on how to setup and run Camera_in Application:

Your video will be live at: https://youtu.be/XNH8jLhjeS4 Part1 of 1

Camera in sample for GR-PEACH. While USER_BUTTON0 is pressed, it will save the image to the USB memory.

The default setting of serial communication (baud rate etc.) in mbed is shown the following link.
Please refer to the link and change the settings of your PC terminal software.
The default value of baud rate in mbed is 9600, and this application uses baud rate 9600.
https://developer.mbed.org/teams/Renesas/wiki/GR-PEACH-Getting-Started#install-the-usb-serial-communication

Please refer to following link about Audio/Camera Shield.
https://developer.mbed.org/teams/Renesas/wiki/Audio_Camera-shield

You can configure this sample application via the following definitions:

main.cpp

/**** User Selection *********/
#define VIDEO_INPUT_METHOD     (VIDEO_CVBS)        /* Select  VIDEO_CVBS or VIDEO_CMOS_CAMERA                       */
#define VIDEO_INPUT_FORMAT     (VIDEO_RGB888)      /* Select  VIDEO_YCBCR422 or VIDEO_RGB888 or VIDEO_RGB565        */
#define USE_VIDEO_CH           (0)                 /* Select  0 or 1            If selecting VIDEO_CMOS_CAMERA, should be 0.)               */
#define VIDEO_PAL              (0)                 /* Select  0(NTSC) or 1(PAL) If selecting VIDEO_CVBS, this parameter is not referenced.) */
/*****************************/

#define PIXEL_HW               (320u)  /* QVGA */
#define PIXEL_VW               (240u)  /* QVGA */


Example of sct file modification is shown below:

MBRZA1H.sct

===Bfore===
    RW_DATA_NC 0x60900000 0x00100000
    { * (NC_DATA) }              ; Application RW data Non cached area

    ZI_DATA_NC +0
    { * (NC_BSS) }               ; Application ZI data Non cached area

===After===
    RW_DATA_NC 0x60800000 0x00100000
    { * (NC_DATA) }              ; Application RW data Non cached area

    ZI_DATA_NC +0
    { * (NC_BSS) }               ; Application ZI data Non cached area


USBHost_Custom\USBHost\TARGET_RENESAS\TARGET_RZ_A1H\usb_host_setting.h

#define USB_HOST_CH                           0
↓
#define USB_HOST_CH                           1

main.cpp

Committer:
Osamu Nakamura
Date:
7 months ago
Revision:
2:9d98159fa9c9
Parent:
1:aaa4b3e0f03c

File content as of revision 2:9d98159fa9c9:

#include "mbed.h"
#include "DisplayBace.h"
#include "FATFileSystem.h"
#include "USBHostMSD.h"
#include "bitmap.h"
#if defined(TARGET_RZ_A1H)
#include "usb_host_setting.h"
#else
#define USB_HOST_CH     0
#endif

#define VIDEO_CVBS             (0)                 /* Analog  Video Signal */
#define VIDEO_CMOS_CAMERA      (1)                 /* Digital Video Signal */
#define VIDEO_YCBCR422         (0)
#define VIDEO_RGB888           (1)
#define VIDEO_RGB565           (2)

/**** User Selection *********/
#define VIDEO_INPUT_METHOD     (VIDEO_CVBS)        /* Select  VIDEO_CVBS or VIDEO_CMOS_CAMERA                       */
#define VIDEO_INPUT_FORMAT     (VIDEO_RGB888)      /* Select  VIDEO_YCBCR422 or VIDEO_RGB888 or VIDEO_RGB565        */
#define USE_VIDEO_CH           (0)                 /* Select  0 or 1            If selecting VIDEO_CMOS_CAMERA, should be 0.)               */
#define VIDEO_PAL              (0)                 /* Select  0(NTSC) or 1(PAL) If selecting VIDEO_CVBS, this parameter is not referenced.) */
/*****************************/

#if USE_VIDEO_CH == (0)
#define VIDEO_INPUT_CH         (DisplayBase::VIDEO_INPUT_CHANNEL_0)
#define VIDEO_INT_TYPE         (DisplayBase::INT_TYPE_S0_VFIELD)
#else
#define VIDEO_INPUT_CH         (DisplayBase::VIDEO_INPUT_CHANNEL_1)
#define VIDEO_INT_TYPE         (DisplayBase::INT_TYPE_S1_VFIELD)
#endif

#if ( VIDEO_INPUT_FORMAT == VIDEO_YCBCR422 || VIDEO_INPUT_FORMAT == VIDEO_RGB565 )
#define DATA_SIZE_PER_PIC      (2u)
#else
#define DATA_SIZE_PER_PIC      (4u)
#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. */
#define PIXEL_HW               (320u)  /* QVGA */
#define PIXEL_VW               (240u)  /* QVGA */
#define VIDEO_BUFFER_STRIDE    (((PIXEL_HW * DATA_SIZE_PER_PIC) + 31u) & ~31u)
#define VIDEO_BUFFER_HEIGHT    (PIXEL_VW)

#if (USB_HOST_CH == 1) //Audio Camera Shield USB1
DigitalOut usb1en(P3_8);
#endif
DigitalOut led1(LED1);
DigitalIn  button(USER_BUTTON0);

#if defined(__ICCARM__)
#pragma data_alignment=16
static uint8_t FrameBuffer_Video_A[VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT]@ ".mirrorram";  //16 bytes aligned!;
static uint8_t FrameBuffer_Video_B[VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT]@ ".mirrorram";  //16 bytes aligned!;
#pragma data_alignment=4
#else
static uint8_t FrameBuffer_Video_A[VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(16)));  //16 bytes aligned!;
static uint8_t FrameBuffer_Video_B[VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(16)));  //16 bytes aligned!;
#endif
static volatile int32_t vsync_count;
static volatile int32_t vfield_count;

/**************************************************************************//**
 * @brief       Interrupt callback function
 * @param[in]   int_type    : VDC5 interrupt type
 * @retval      None
******************************************************************************/
static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type)
{
    if (vfield_count > 0) {
        vfield_count--;
    }
}

/**************************************************************************//**
 * @brief       Wait for the specified number of times Vsync occurs
 * @param[in]   wait_count          : Wait count
 * @retval      None
******************************************************************************/
static void WaitVfield(const int32_t wait_count)
{
    vfield_count = wait_count;
    while (vfield_count > 0) {
        /* Do nothing */
    }
}

/**************************************************************************//**
 * @brief       Interrupt callback function for Vsync interruption
 * @param[in]   int_type    : VDC5 interrupt type
 * @retval      None
******************************************************************************/
static void IntCallbackFunc_Vsync(DisplayBase::int_type_t int_type)
{
    if (vsync_count > 0) {
        vsync_count--;
    }
}

/**************************************************************************//**
 * @brief       Wait for the specified number of times Vsync occurs
 * @param[in]   wait_count          : Wait count
 * @retval      None
******************************************************************************/
static void WaitVsync(const int32_t wait_count)
{
    vsync_count = wait_count;
    while (vsync_count > 0) {
        /* Do nothing */
    }
}

/**************************************************************************//**
 * @brief
 * @param[in]   void
 * @retval      None
******************************************************************************/
int main(void)
{
    DisplayBase::graphics_error_t error;
    uint8_t * write_buff_addr = FrameBuffer_Video_A;
    uint8_t * save_buff_addr  = FrameBuffer_Video_B;

#if VIDEO_INPUT_METHOD == VIDEO_CMOS_CAMERA
    DisplayBase::video_ext_in_config_t ext_in_config;
    PinName cmos_camera_pin[11] = {
        /* data pin */
        P2_7, P2_6, P2_5, P2_4, P2_3, P2_2, P2_1, P2_0,
        /* control pin */
        P10_0,      /* DV0_CLK   */
        P1_0,       /* DV0_Vsync */
        P1_1        /* DV0_Hsync */
    };
#endif

    /* Create DisplayBase object */
    DisplayBase Display;

    /* Graphics initialization process */
    error = Display.Graphics_init(NULL);
    if (error != DisplayBase::GRAPHICS_OK) {
        printf("Line %d, error %d\n", __LINE__, error);
        while (1);
    }

#if VIDEO_INPUT_METHOD == VIDEO_CVBS
    error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_VDEC, NULL);
    if( error != DisplayBase::GRAPHICS_OK ) {
        while(1);
    }

#elif VIDEO_INPUT_METHOD == VIDEO_CMOS_CAMERA
    /* MT9V111 camera input config */
    ext_in_config.inp_format     = DisplayBase::VIDEO_EXTIN_FORMAT_BT601; /* BT601 8bit YCbCr format */
    ext_in_config.inp_pxd_edge   = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing data          */
    ext_in_config.inp_vs_edge    = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing Vsync signals */
    ext_in_config.inp_hs_edge    = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing Hsync signals */
    ext_in_config.inp_endian_on  = DisplayBase::OFF;                      /* External input bit endian change on/off       */
    ext_in_config.inp_swap_on    = DisplayBase::OFF;                      /* External input B/R signal swap on/off         */
    ext_in_config.inp_vs_inv     = DisplayBase::SIG_POL_NOT_INVERTED;     /* External input DV_VSYNC inversion control     */
    ext_in_config.inp_hs_inv     = DisplayBase::SIG_POL_INVERTED;         /* External input DV_HSYNC inversion control     */
    ext_in_config.inp_f525_625   = DisplayBase::EXTIN_LINE_525;           /* Number of lines for BT.656 external input */
    ext_in_config.inp_h_pos      = DisplayBase::EXTIN_H_POS_CRYCBY;       /* Y/Cb/Y/Cr data string start timing to Hsync reference */
    ext_in_config.cap_vs_pos     = 6;                                     /* Capture start position from Vsync */
    ext_in_config.cap_hs_pos     = 150;                                   /* Capture start position form Hsync */
    ext_in_config.cap_width      = 640;                                   /* Capture width  */
    ext_in_config.cap_height     = 468u;                                  /* Capture height Max 468[line]
                                                                             Due to CMOS(MT9V111) output signal timing and VDC5 specification */
    error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_EXT, &ext_in_config);
    if( error != DisplayBase::GRAPHICS_OK ) {
        printf("Line %d, error %d\n", __LINE__, error);
        while(1);
    }

    /* MT9V111 camera input port setting */
    error = Display.Graphics_Dvinput_Port_Init(cmos_camera_pin, 11);
    if( error != DisplayBase::GRAPHICS_OK ) {
        printf("Line %d, error %d\n", __LINE__, error);
        while (1);
    }
#endif

    /* Interrupt callback function setting (Vsync signal input to scaler 0) */
    error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VI_VSYNC, 0, IntCallbackFunc_Vsync);
    if (error != DisplayBase::GRAPHICS_OK) {
        printf("Line %d, error %d\n", __LINE__, error);
        while (1);
    }
    /* Video capture setting (progressive form fixed) */
    error = Display.Video_Write_Setting(
                VIDEO_INPUT_CH,
#if VIDEO_PAL == 0
                DisplayBase::COL_SYS_NTSC_358,
#else
                DisplayBase::COL_SYS_PAL_443,
#endif
                write_buff_addr,
                VIDEO_BUFFER_STRIDE,
#if VIDEO_INPUT_FORMAT == VIDEO_YCBCR422
                DisplayBase::VIDEO_FORMAT_YCBCR422,
                DisplayBase::WR_RD_WRSWA_NON,
#elif VIDEO_INPUT_FORMAT == VIDEO_RGB565
                DisplayBase::VIDEO_FORMAT_RGB565,
                DisplayBase::WR_RD_WRSWA_32_16BIT,
#else
                DisplayBase::VIDEO_FORMAT_RGB888,
                DisplayBase::WR_RD_WRSWA_32BIT,
#endif
                PIXEL_VW,
                PIXEL_HW
            );
    if (error != DisplayBase::GRAPHICS_OK) {
        printf("Line %d, error %d\n", __LINE__, error);
        while (1);
    }

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

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

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

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

    /* Wait vsync to update resister */
    WaitVsync(1);

    /* Wait 2 Vfield(Top or bottom field) */
    WaitVfield(2);

#if (USB_HOST_CH == 1) //Audio Shield USB1
    //Audio Shield USB1 enable
    usb1en = 1;        //Outputs high level
    Thread::wait(5);
    usb1en = 0;        //Outputs low level
#endif
    FATFileSystem fs("usb");
    USBHostMSD msd;
    char file_name[32];
    int file_name_index = 0;
    int save_file_size;

    while (1) {
        /* button check */
        if (button == 0) {
            led1 = 1;
            if (write_buff_addr == FrameBuffer_Video_A) {
                write_buff_addr = FrameBuffer_Video_B;
                save_buff_addr  = FrameBuffer_Video_A;
            } else {
                write_buff_addr = FrameBuffer_Video_A;
                save_buff_addr  = FrameBuffer_Video_B;
            }

            /* Change write buffer */
            error = Display.Video_Write_Change(
                        VIDEO_INPUT_CH,
                        write_buff_addr,
                        VIDEO_BUFFER_STRIDE);
            if (error != DisplayBase::GRAPHICS_OK) {
                printf("Line %d, error %d\n", __LINE__, error);
                while (1);
            }
            /* Wait 2 Vfield(Top or bottom field) */
            WaitVfield(2);

            /* Now, the captture into FrameBuffer_Video_AorB is completed */
            /* Then, chech if USB flash disk is connected */
            while (!msd.connected()) {
                if (!msd.connect()) {
                    Thread::wait(500);
                } else {
                    /* USB flash disk is connected */
                    fs.mount(&msd);
                    break;
                }
            }

            /* Data save */
#if ( VIDEO_INPUT_FORMAT == VIDEO_YCBCR422 || VIDEO_INPUT_FORMAT == VIDEO_RGB565 )
            /* Save ".bin" file */
            sprintf(file_name, "/usb/video_%d.bin", file_name_index++);
            FILE * fp = fopen(file_name, "w");
            save_file_size = fwrite(save_buff_addr, sizeof(char), (VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT), fp);
            fclose(fp);
#else
            /* Save ".bmp" file */
            sprintf(file_name, "/usb/video_%d.bmp", file_name_index++);

            bitmap bitmapfile;
            save_file_size = bitmapfile.Rgb888ToBmp(file_name, save_buff_addr, PIXEL_HW, PIXEL_VW);
#endif
            printf("file name %s, file size %d\n", file_name, save_file_size);
            led1 = 0;
        }
    }
}