Yoshihiro Michimoto / Mbed OS GR-PEACH_Camera_in

Dependencies:   GR-PEACH_video USBHost USBHost_custom

Fork of GR-PEACH_Camera_in by Renesas

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "DisplayBace.h"
00003 #include "FATFileSystem.h"
00004 #include "USBHostMSD.h"
00005 #include "bitmap.h "
00006 #if defined(TARGET_RZ_A1H)
00007 #include "usb_host_setting.h"
00008 #else
00009 #define USB_HOST_CH     0
00010 #endif
00011 
00012 #define VIDEO_CVBS             (0)                 /* Analog  Video Signal */
00013 #define VIDEO_CMOS_CAMERA      (1)                 /* Digital Video Signal */
00014 #define VIDEO_YCBCR422         (0)
00015 #define VIDEO_RGB888           (1)
00016 #define VIDEO_RGB565           (2)
00017 
00018 /**** User Selection *********/
00019 #define VIDEO_INPUT_METHOD     (VIDEO_CVBS)        /* Select  VIDEO_CVBS or VIDEO_CMOS_CAMERA                       */
00020 #define VIDEO_INPUT_FORMAT     (VIDEO_RGB888)      /* Select  VIDEO_YCBCR422 or VIDEO_RGB888 or VIDEO_RGB565        */
00021 #define USE_VIDEO_CH           (0)                 /* Select  0 or 1            If selecting VIDEO_CMOS_CAMERA, should be 0.)               */
00022 #define VIDEO_PAL              (0)                 /* Select  0(NTSC) or 1(PAL) If selecting VIDEO_CVBS, this parameter is not referenced.) */
00023 /*****************************/
00024 
00025 #if USE_VIDEO_CH == (0)
00026 #define VIDEO_INPUT_CH         (DisplayBase::VIDEO_INPUT_CHANNEL_0)
00027 #define VIDEO_INT_TYPE         (DisplayBase::INT_TYPE_S0_VFIELD)
00028 #else
00029 #define VIDEO_INPUT_CH         (DisplayBase::VIDEO_INPUT_CHANNEL_1)
00030 #define VIDEO_INT_TYPE         (DisplayBase::INT_TYPE_S1_VFIELD)
00031 #endif
00032 
00033 #if ( VIDEO_INPUT_FORMAT == VIDEO_YCBCR422 || VIDEO_INPUT_FORMAT == VIDEO_RGB565 )
00034 #define DATA_SIZE_PER_PIC      (2u)
00035 #else
00036 #define DATA_SIZE_PER_PIC      (4u)
00037 #endif
00038 
00039 /*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128
00040     in accordance with the frame buffer burst transfer mode. */
00041 #define PIXEL_HW               (320u)  /* QVGA */
00042 #define PIXEL_VW               (240u)  /* QVGA */
00043 #define VIDEO_BUFFER_STRIDE    (((PIXEL_HW * DATA_SIZE_PER_PIC) + 31u) & ~31u)
00044 #define VIDEO_BUFFER_HEIGHT    (PIXEL_VW)
00045 
00046 #if (USB_HOST_CH == 1) //Audio Camera Shield USB1
00047 DigitalOut usb1en(P3_8);
00048 #endif
00049 DigitalOut led1(LED1);
00050 DigitalIn  button(USER_BUTTON0);
00051 
00052 #if defined(__ICCARM__)
00053 #pragma data_alignment=16
00054 static uint8_t FrameBuffer_Video_A[VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT]@ ".mirrorram";  //16 bytes aligned!;
00055 static uint8_t FrameBuffer_Video_B[VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT]@ ".mirrorram";  //16 bytes aligned!;
00056 #pragma data_alignment=4
00057 #else
00058 static uint8_t FrameBuffer_Video_A[VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(16)));  //16 bytes aligned!;
00059 static uint8_t FrameBuffer_Video_B[VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(16)));  //16 bytes aligned!;
00060 #endif
00061 static volatile int32_t vsync_count;
00062 static volatile int32_t vfield_count;
00063 
00064 /**************************************************************************//**
00065  * @brief       Interrupt callback function
00066  * @param[in]   int_type    : VDC5 interrupt type
00067  * @retval      None
00068 ******************************************************************************/
00069 static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type)
00070 {
00071     if (vfield_count > 0) {
00072         vfield_count--;
00073     }
00074 }
00075 
00076 /**************************************************************************//**
00077  * @brief       Wait for the specified number of times Vsync occurs
00078  * @param[in]   wait_count          : Wait count
00079  * @retval      None
00080 ******************************************************************************/
00081 static void WaitVfield(const int32_t wait_count)
00082 {
00083     vfield_count = wait_count;
00084     while (vfield_count > 0) {
00085         /* Do nothing */
00086     }
00087 }
00088 
00089 /**************************************************************************//**
00090  * @brief       Interrupt callback function for Vsync interruption
00091  * @param[in]   int_type    : VDC5 interrupt type
00092  * @retval      None
00093 ******************************************************************************/
00094 static void IntCallbackFunc_Vsync(DisplayBase::int_type_t int_type)
00095 {
00096     if (vsync_count > 0) {
00097         vsync_count--;
00098     }
00099 }
00100 
00101 /**************************************************************************//**
00102  * @brief       Wait for the specified number of times Vsync occurs
00103  * @param[in]   wait_count          : Wait count
00104  * @retval      None
00105 ******************************************************************************/
00106 static void WaitVsync(const int32_t wait_count)
00107 {
00108     vsync_count = wait_count;
00109     while (vsync_count > 0) {
00110         /* Do nothing */
00111     }
00112 }
00113 
00114 /**************************************************************************//**
00115  * @brief
00116  * @param[in]   void
00117  * @retval      None
00118 ******************************************************************************/
00119 int main(void)
00120 {
00121     DisplayBase::graphics_error_t error;
00122     uint8_t * write_buff_addr = FrameBuffer_Video_A;
00123     uint8_t * save_buff_addr  = FrameBuffer_Video_B;
00124 
00125 #if VIDEO_INPUT_METHOD == VIDEO_CMOS_CAMERA
00126     DisplayBase::video_ext_in_config_t ext_in_config;
00127     PinName cmos_camera_pin[11] = {
00128         /* data pin */
00129         P2_7, P2_6, P2_5, P2_4, P2_3, P2_2, P2_1, P2_0,
00130         /* control pin */
00131         P10_0,      /* DV0_CLK   */
00132         P1_0,       /* DV0_Vsync */
00133         P1_1        /* DV0_Hsync */
00134     };
00135 #endif
00136 
00137     /* Create DisplayBase object */
00138     DisplayBase Display;
00139 
00140     /* Graphics initialization process */
00141     error = Display.Graphics_init(NULL);
00142     if (error != DisplayBase::GRAPHICS_OK) {
00143         printf("Line %d, error %d\n", __LINE__, error);
00144         while (1);
00145     }
00146 
00147 #if VIDEO_INPUT_METHOD == VIDEO_CVBS
00148     error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_VDEC, NULL);
00149     if( error != DisplayBase::GRAPHICS_OK ) {
00150         while(1);
00151     }
00152 
00153 #elif VIDEO_INPUT_METHOD == VIDEO_CMOS_CAMERA
00154     /* MT9V111 camera input config */
00155     ext_in_config.inp_format     = DisplayBase::VIDEO_EXTIN_FORMAT_BT601; /* BT601 8bit YCbCr format */
00156     ext_in_config.inp_pxd_edge   = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing data          */
00157     ext_in_config.inp_vs_edge    = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing Vsync signals */
00158     ext_in_config.inp_hs_edge    = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing Hsync signals */
00159     ext_in_config.inp_endian_on  = DisplayBase::OFF;                      /* External input bit endian change on/off       */
00160     ext_in_config.inp_swap_on    = DisplayBase::OFF;                      /* External input B/R signal swap on/off         */
00161     ext_in_config.inp_vs_inv     = DisplayBase::SIG_POL_NOT_INVERTED;     /* External input DV_VSYNC inversion control     */
00162     ext_in_config.inp_hs_inv     = DisplayBase::SIG_POL_INVERTED;         /* External input DV_HSYNC inversion control     */
00163     ext_in_config.inp_f525_625   = DisplayBase::EXTIN_LINE_525;           /* Number of lines for BT.656 external input */
00164     ext_in_config.inp_h_pos      = DisplayBase::EXTIN_H_POS_CRYCBY;       /* Y/Cb/Y/Cr data string start timing to Hsync reference */
00165     ext_in_config.cap_vs_pos     = 6;                                     /* Capture start position from Vsync */
00166     ext_in_config.cap_hs_pos     = 150;                                   /* Capture start position form Hsync */
00167     ext_in_config.cap_width      = 640;                                   /* Capture width  */
00168     ext_in_config.cap_height     = 468u;                                  /* Capture height Max 468[line]
00169                                                                              Due to CMOS(MT9V111) output signal timing and VDC5 specification */
00170     error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_EXT, &ext_in_config);
00171     if( error != DisplayBase::GRAPHICS_OK ) {
00172         printf("Line %d, error %d\n", __LINE__, error);
00173         while(1);
00174     }
00175 
00176     /* MT9V111 camera input port setting */
00177     error = Display.Graphics_Dvinput_Port_Init(cmos_camera_pin, 11);
00178     if( error != DisplayBase::GRAPHICS_OK ) {
00179         printf("Line %d, error %d\n", __LINE__, error);
00180         while (1);
00181     }
00182 #endif
00183 
00184     /* Interrupt callback function setting (Vsync signal input to scaler 0) */
00185     error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VI_VSYNC, 0, IntCallbackFunc_Vsync);
00186     if (error != DisplayBase::GRAPHICS_OK) {
00187         printf("Line %d, error %d\n", __LINE__, error);
00188         while (1);
00189     }
00190     /* Video capture setting (progressive form fixed) */
00191     error = Display.Video_Write_Setting(
00192                 VIDEO_INPUT_CH,
00193 #if VIDEO_PAL == 0
00194                 DisplayBase::COL_SYS_NTSC_358,
00195 #else
00196                 DisplayBase::COL_SYS_PAL_443,
00197 #endif
00198                 write_buff_addr,
00199                 VIDEO_BUFFER_STRIDE,
00200 #if VIDEO_INPUT_FORMAT == VIDEO_YCBCR422
00201                 DisplayBase::VIDEO_FORMAT_YCBCR422,
00202                 DisplayBase::WR_RD_WRSWA_NON,
00203 #elif VIDEO_INPUT_FORMAT == VIDEO_RGB565
00204                 DisplayBase::VIDEO_FORMAT_RGB565,
00205                 DisplayBase::WR_RD_WRSWA_32_16BIT,
00206 #else
00207                 DisplayBase::VIDEO_FORMAT_RGB888,
00208                 DisplayBase::WR_RD_WRSWA_32BIT,
00209 #endif
00210                 PIXEL_VW,
00211                 PIXEL_HW
00212             );
00213     if (error != DisplayBase::GRAPHICS_OK) {
00214         printf("Line %d, error %d\n", __LINE__, error);
00215         while (1);
00216     }
00217 
00218     /* Interrupt callback function setting (Field end signal for recording function in scaler 0) */
00219     error = Display.Graphics_Irq_Handler_Set(VIDEO_INT_TYPE, 0, IntCallbackFunc_Vfield);
00220     if (error != DisplayBase::GRAPHICS_OK) {
00221         printf("Line %d, error %d\n", __LINE__, error);
00222         while (1);
00223     }
00224 
00225     /* Video write process start */
00226     error = Display.Video_Start (VIDEO_INPUT_CH);
00227     if (error != DisplayBase::GRAPHICS_OK) {
00228         printf("Line %d, error %d\n", __LINE__, error);
00229         while (1);
00230     }
00231 
00232     /* Video write process stop */
00233     error = Display.Video_Stop (VIDEO_INPUT_CH);
00234     if (error != DisplayBase::GRAPHICS_OK) {
00235         printf("Line %d, error %d\n", __LINE__, error);
00236         while (1);
00237     }
00238 
00239     /* Video write process start */
00240     error = Display.Video_Start (VIDEO_INPUT_CH);
00241     if (error != DisplayBase::GRAPHICS_OK) {
00242         printf("Line %d, error %d\n", __LINE__, error);
00243         while (1);
00244     }
00245 
00246     /* Wait vsync to update resister */
00247     WaitVsync(1);
00248 
00249     /* Wait 2 Vfield(Top or bottom field) */
00250     WaitVfield(2);
00251 
00252 #if (USB_HOST_CH == 1) //Audio Shield USB1
00253     //Audio Shield USB1 enable
00254     usb1en = 1;        //Outputs high level
00255     Thread::wait(5);
00256     usb1en = 0;        //Outputs low level
00257 #endif
00258     FATFileSystem fs("usb");
00259     USBHostMSD msd;
00260     char file_name[32];
00261     int file_name_index = 0;
00262     int save_file_size;
00263 
00264     while (1) {
00265         /* button check */
00266         if (button == 0) {
00267             led1 = 1;
00268             if (write_buff_addr == FrameBuffer_Video_A) {
00269                 write_buff_addr = FrameBuffer_Video_B;
00270                 save_buff_addr  = FrameBuffer_Video_A;
00271             } else {
00272                 write_buff_addr = FrameBuffer_Video_A;
00273                 save_buff_addr  = FrameBuffer_Video_B;
00274             }
00275 
00276             /* Change write buffer */
00277             error = Display.Video_Write_Change(
00278                         VIDEO_INPUT_CH,
00279                         write_buff_addr,
00280                         VIDEO_BUFFER_STRIDE);
00281             if (error != DisplayBase::GRAPHICS_OK) {
00282                 printf("Line %d, error %d\n", __LINE__, error);
00283                 while (1);
00284             }
00285             /* Wait 2 Vfield(Top or bottom field) */
00286             WaitVfield(2);
00287 
00288             /* Now, the captture into FrameBuffer_Video_AorB is completed */
00289             /* Then, chech if USB flash disk is connected */
00290             while (!msd.connected()) {
00291                 if (!msd.connect()) {
00292                     Thread::wait(500);
00293                 } else {
00294                     /* USB flash disk is connected */
00295                     fs.mount(&msd);
00296                     break;
00297                 }
00298             }
00299 
00300             /* Data save */
00301 #if ( VIDEO_INPUT_FORMAT == VIDEO_YCBCR422 || VIDEO_INPUT_FORMAT == VIDEO_RGB565 )
00302             /* Save ".bin" file */
00303             sprintf(file_name, "/usb/video_%d.bin", file_name_index++);
00304             FILE * fp = fopen(file_name, "w");
00305             save_file_size = fwrite(save_buff_addr, sizeof(char), (VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT), fp);
00306             fclose(fp);
00307 #else
00308             /* Save ".bmp" file */
00309             sprintf(file_name, "/usb/video_%d.bmp", file_name_index++);
00310 
00311             bitmap bitmapfile;
00312             save_file_size = bitmapfile.Rgb888ToBmp(file_name, save_buff_addr, PIXEL_HW, PIXEL_VW);
00313 #endif
00314             printf("file name %s, file size %d\n", file_name, save_file_size);
00315             led1 = 0;
00316         }
00317     }
00318 }