Ryo Hagimoto / Mbed 2 deprecated GR-PEACH_WebCamera_OV5642_fixedIP

Dependencies:   EthernetInterface FATFileSystem GR-PEACH_video GraphicsFramework HttpServer_snapshot R_BSP mbed-rpc mbed-rtos mbed

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 "rtos.h"
00004 #include "JPEG_Converter.h"
00005 #include "EthernetInterface.h"
00006 #include "HTTPServer.h"
00007 #include "mbed_rpc.h"
00008 #include "RomRamFileSystem.h"
00009 #include "file_table.h"        //Binary data of web pages
00010 #include "i2c_setting.h"
00011 #include "camera_config.h"
00012 
00013 #define VIDEO_CVBS             (0)                 /* Analog  Video Signal */
00014 #define VIDEO_CMOS_CAMERA      (1)                 /* Digital Video Signal */
00015 #define VIDEO_YCBCR422         (0)
00016 #define VIDEO_RGB888           (1)
00017 #define VIDEO_RGB565           (2)
00018 
00019 /**** User Selection *********/
00020 /** Network setting **/
00021 #define USE_DHCP               (0)                 /* Select  0(static configuration) or 1(use DHCP) */
00022 #if (USE_DHCP == 0)
00023   #define IP_ADDRESS           ("192.168.0.2")     /* IP address      */
00024   #define SUBNET_MASK          ("255.255.255.0")   /* Subnet mask     */
00025   #define DEFAULT_GATEWAY      ("192.168.0.3")     /* Default gateway */
00026 #endif
00027 /** Camera setting **/
00028 #define VIDEO_INPUT_METHOD     (VIDEO_CMOS_CAMERA) /* Select  VIDEO_CVBS or VIDEO_CMOS_CAMERA                       */
00029 #define VIDEO_INPUT_FORMAT     (VIDEO_YCBCR422)    /* Select  VIDEO_YCBCR422 or VIDEO_RGB888 or VIDEO_RGB565        */
00030 #define USE_VIDEO_CH           (0)                 /* Select  0 or 1            If selecting VIDEO_CMOS_CAMERA, should be 0.)               */
00031 #define VIDEO_PAL              (0)                 /* Select  0(NTSC) or 1(PAL) If selecting VIDEO_CVBS, this parameter is not referenced.) */
00032 /*****************************/
00033 
00034 #if USE_VIDEO_CH == (0)
00035 #define VIDEO_INPUT_CH         (DisplayBase::VIDEO_INPUT_CHANNEL_0)
00036 #define VIDEO_INT_TYPE         (DisplayBase::INT_TYPE_S0_VFIELD)
00037 #else
00038 #define VIDEO_INPUT_CH         (DisplayBase::VIDEO_INPUT_CHANNEL_1)
00039 #define VIDEO_INT_TYPE         (DisplayBase::INT_TYPE_S1_VFIELD)
00040 #endif
00041 
00042 #if ( VIDEO_INPUT_FORMAT == VIDEO_YCBCR422 || VIDEO_INPUT_FORMAT == VIDEO_RGB565 )
00043 #define DATA_SIZE_PER_PIC      (2u)
00044 #else
00045 #define DATA_SIZE_PER_PIC      (4u)
00046 #endif
00047 
00048 /*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128
00049     in accordance with the frame buffer burst transfer mode. */
00050 #if (1) /* for OV4652 */
00051 #define PIXEL_HW               (640u)  /* VGA */
00052 #define PIXEL_VW               (480u)  /* VGA */
00053 #else
00054 #define PIXEL_HW               (320u)  /* QVGA */
00055 #define PIXEL_VW               (240u)  /* QVGA */
00056 #endif
00057 
00058 #define VIDEO_BUFFER_STRIDE    (((PIXEL_HW * DATA_SIZE_PER_PIC) + 31u) & ~31u)
00059 #define VIDEO_BUFFER_HEIGHT    (PIXEL_VW)
00060 
00061 #define OV5642_INIT_BUF_SIZE    17
00062 
00063 EthernetInterface network;
00064 RomRamFileSystem romramfs("romram");
00065 
00066 #if defined(__ICCARM__)
00067 #pragma data_alignment=16
00068 static uint8_t FrameBuffer_Video[VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT]@ ".mirrorram";  //16 bytes aligned!;
00069 #pragma data_alignment=4
00070 #else
00071 static uint8_t FrameBuffer_Video[VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(16)));  //16 bytes aligned!;
00072 #endif
00073 static volatile int32_t vsync_count = 0;
00074 static volatile int32_t vfield_count = 1;
00075 #if (1) /* for OV5642 */
00076 #if defined(__ICCARM__)
00077 #pragma data_alignment=8
00078 static uint8_t JpegBuffer[2][1024 * 100]@ ".mirrorram";  //8 bytes aligned!;
00079 #pragma data_alignment=4
00080 #else
00081 static uint8_t JpegBuffer[2][1024 * 100]__attribute((section("NC_BSS"),aligned(8)));  //8 bytes aligned!;
00082 #endif
00083 #else /* for OV5642 */
00084 #if defined(__ICCARM__)
00085 #pragma data_alignment=8
00086 static uint8_t JpegBuffer[2][1024 * 50]@ ".mirrorram";  //8 bytes aligned!;
00087 #pragma data_alignment=4
00088 #else
00089 static uint8_t JpegBuffer[2][1024 * 50]__attribute((section("NC_BSS"),aligned(8)));  //8 bytes aligned!;
00090 #endif
00091 #endif /* for OV5642 */
00092 static size_t jcu_encode_size[2];
00093 static int image_change = 0;
00094 JPEG_Converter Jcu;
00095 static int jcu_buf_index_write = 0;
00096 static int jcu_buf_index_write_done = 0;
00097 static int jcu_buf_index_read = 0;
00098 static int jcu_encoding = 0;
00099 static char i2c_setting_str_buf[I2C_SETTING_STR_BUF_SIZE];
00100 
00101 extern void analy_and_exe(char * buf);
00102 static void OV5642_Init(void) {
00103     char camera_init_buffer[OV5642_INIT_BUF_SIZE];
00104     int cnt;
00105 
00106     for(cnt = 0; cnt < OV5642_INIT_TBL_NUM; cnt++) {
00107         memcpy(&camera_init_buffer[0], cam_init_tbl[cnt], OV5642_INIT_BUF_SIZE);
00108         i2c_setting_exe(&camera_init_buffer[0]);
00109     }
00110 }
00111 
00112 static void JcuEncodeCallBackFunc(JPEG_Converter::jpeg_conv_error_t err_code) {
00113     jcu_buf_index_write_done = jcu_buf_index_write;
00114     image_change = 1;
00115     jcu_encoding = 0;
00116 }
00117 
00118 static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) {
00119     //Interrupt callback function
00120     if (vfield_count != 0) {
00121         vfield_count = 0;
00122     } else {
00123         vfield_count = 1;
00124 
00125         JPEG_Converter::bitmap_buff_info_t bitmap_buff_info;
00126         JPEG_Converter::encode_options_t   encode_options;
00127 
00128         bitmap_buff_info.width          = PIXEL_HW;
00129         bitmap_buff_info.height         = PIXEL_VW;
00130         bitmap_buff_info.format         = JPEG_Converter::WR_RD_YCbCr422;
00131         bitmap_buff_info.buffer_address = (void *)FrameBuffer_Video;
00132 
00133         encode_options.encode_buff_size = sizeof(JpegBuffer[0]);
00134         encode_options.p_EncodeCallBackFunc = &JcuEncodeCallBackFunc;
00135 
00136         jcu_encoding = 1;
00137         if (jcu_buf_index_read == jcu_buf_index_write) {
00138             if (jcu_buf_index_write != 0) {
00139                 jcu_buf_index_write = 0;
00140             } else {
00141                 jcu_buf_index_write = 1;
00142             }
00143         }
00144         jcu_encode_size[jcu_buf_index_write] = 0;
00145         if (Jcu.encode(&bitmap_buff_info, JpegBuffer[jcu_buf_index_write], &jcu_encode_size[jcu_buf_index_write], &encode_options) != JPEG_Converter::JPEG_CONV_OK) {
00146             jcu_encode_size[jcu_buf_index_write] = 0;
00147             jcu_encoding = 0;
00148         }
00149     }
00150 }
00151 
00152 static void IntCallbackFunc_Vsync(DisplayBase::int_type_t int_type) {
00153     //Interrupt callback function for Vsync interruption
00154     if (vsync_count > 0) {
00155         vsync_count--;
00156     }
00157 }
00158 
00159 static void WaitVsync(const int32_t wait_count) {
00160     //Wait for the specified number of times Vsync occurs
00161     vsync_count = wait_count;
00162     while (vsync_count > 0) {
00163         /* Do nothing */
00164     }
00165 }
00166 
00167 static void camera_start(void) {
00168     DisplayBase::graphics_error_t error;
00169 
00170 #if VIDEO_INPUT_METHOD == VIDEO_CMOS_CAMERA
00171     DisplayBase::video_ext_in_config_t ext_in_config;
00172     PinName cmos_camera_pin[11] = {
00173         /* data pin */
00174         P2_7, P2_6, P2_5, P2_4, P2_3, P2_2, P2_1, P2_0,
00175         /* control pin */
00176         P10_0,      /* DV0_CLK   */
00177         P1_0,       /* DV0_Vsync */
00178         P1_1        /* DV0_Hsync */
00179     };
00180 #endif
00181 
00182     /* Initialize OV5642 */
00183     OV5642_Init();
00184 
00185     /* Create DisplayBase object */
00186     DisplayBase Display;
00187 
00188     /* Graphics initialization process */
00189     error = Display.Graphics_init(NULL);
00190     if (error != DisplayBase::GRAPHICS_OK) {
00191         printf("Line %d, error %d\n", __LINE__, error);
00192         while (1);
00193     }
00194 
00195 #if VIDEO_INPUT_METHOD == VIDEO_CVBS
00196     error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_VDEC, NULL);
00197     if( error != DisplayBase::GRAPHICS_OK ) {
00198         printf("Line %d, error %d\n", __LINE__, error);
00199         while(1);
00200     }
00201 
00202 #elif VIDEO_INPUT_METHOD == VIDEO_CMOS_CAMERA
00203     /* MT9V111 camera input config */
00204     ext_in_config.inp_format     = DisplayBase::VIDEO_EXTIN_FORMAT_BT601; /* BT601 8bit YCbCr format */
00205     ext_in_config.inp_pxd_edge   = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing data          */
00206     ext_in_config.inp_vs_edge    = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing Vsync signals */
00207     ext_in_config.inp_hs_edge    = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing Hsync signals */
00208     ext_in_config.inp_endian_on  = DisplayBase::OFF;                      /* External input bit endian change on/off       */
00209     ext_in_config.inp_swap_on    = DisplayBase::OFF;                      /* External input B/R signal swap on/off         */
00210     ext_in_config.inp_vs_inv     = DisplayBase::SIG_POL_NOT_INVERTED;     /* External input DV_VSYNC inversion control     */
00211 #if (1) /* for OV4652 */
00212     ext_in_config.inp_hs_inv     = DisplayBase::SIG_POL_NOT_INVERTED;     /* External input DV_HSYNC inversion control     */
00213 #else
00214     ext_in_config.inp_hs_inv     = DisplayBase::SIG_POL_INVERTED;         /* External input DV_HSYNC inversion control     */
00215 #endif
00216    ext_in_config.inp_f525_625   = DisplayBase::EXTIN_LINE_525;           /* Number of lines for BT.656 external input */
00217 #if (1) /* for OV4652 */
00218     ext_in_config.inp_h_pos      = DisplayBase::EXTIN_H_POS_YCBYCR;       /* Y/Cb/Y/Cr data string start timing to Hsync reference */
00219     ext_in_config.cap_vs_pos     = 5;                                     /* Capture start position from Vsync */
00220     ext_in_config.cap_hs_pos     = 16;                                    /* Capture start position form Hsync */
00221     ext_in_config.cap_width      = ((640u-16u));                          /* Capture width  */
00222     ext_in_config.cap_height     = 468u;                                  /* Capture height Max 468[line]
00223                                                                              Due to CMOS(MT9V111) output signal timing and VDC5 specification */
00224 #else
00225     ext_in_config.inp_h_pos      = DisplayBase::EXTIN_H_POS_CRYCBY;       /* Y/Cb/Y/Cr data string start timing to Hsync reference */
00226     ext_in_config.cap_vs_pos     = 6;                                     /* Capture start position from Vsync */
00227     ext_in_config.cap_hs_pos     = 150;                                   /* Capture start position form Hsync */
00228     ext_in_config.cap_width      = 640;                                   /* Capture width  */
00229     ext_in_config.cap_height     = 468u;                                  /* Capture height Max 468[line]
00230                                                                              Due to CMOS(MT9V111) output signal timing and VDC5 specification */
00231 #endif
00232     error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_EXT, &ext_in_config);
00233     if( error != DisplayBase::GRAPHICS_OK ) {
00234         printf("Line %d, error %d\n", __LINE__, error);
00235         while(1);
00236     }
00237 
00238     /* MT9V111 camera input port setting */
00239     error = Display.Graphics_Dvinput_Port_Init(cmos_camera_pin, 11);
00240     if( error != DisplayBase::GRAPHICS_OK ) {
00241         printf("Line %d, error %d\n", __LINE__, error);
00242         while (1);
00243     }
00244 #endif
00245 
00246     /* Interrupt callback function setting (Vsync signal input to scaler 0) */
00247     error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VI_VSYNC, 0, IntCallbackFunc_Vsync);
00248     if (error != DisplayBase::GRAPHICS_OK) {
00249         printf("Line %d, error %d\n", __LINE__, error);
00250         while (1);
00251     }
00252     /* Video capture setting (progressive form fixed) */
00253     error = Display.Video_Write_Setting(
00254                 VIDEO_INPUT_CH,
00255 #if VIDEO_PAL == 0
00256                 DisplayBase::COL_SYS_NTSC_358,
00257 #else
00258                 DisplayBase::COL_SYS_PAL_443,
00259 #endif
00260                 FrameBuffer_Video,
00261                 VIDEO_BUFFER_STRIDE,
00262 #if VIDEO_INPUT_FORMAT == VIDEO_YCBCR422
00263                 DisplayBase::VIDEO_FORMAT_YCBCR422,
00264                 DisplayBase::WR_RD_WRSWA_NON,
00265 #elif VIDEO_INPUT_FORMAT == VIDEO_RGB565
00266                 DisplayBase::VIDEO_FORMAT_RGB565,
00267                 DisplayBase::WR_RD_WRSWA_32_16BIT,
00268 #else
00269                 DisplayBase::VIDEO_FORMAT_RGB888,
00270                 DisplayBase::WR_RD_WRSWA_32BIT,
00271 #endif
00272                 PIXEL_VW,
00273                 PIXEL_HW
00274             );
00275     if (error != DisplayBase::GRAPHICS_OK) {
00276         printf("Line %d, error %d\n", __LINE__, error);
00277         while (1);
00278     }
00279 
00280     /* Interrupt callback function setting (Field end signal for recording function in scaler 0) */
00281     error = Display.Graphics_Irq_Handler_Set(VIDEO_INT_TYPE, 0, IntCallbackFunc_Vfield);
00282     if (error != DisplayBase::GRAPHICS_OK) {
00283         printf("Line %d, error %d\n", __LINE__, error);
00284         while (1);
00285     }
00286 
00287     /* Video write process start */
00288     error = Display.Video_Start (VIDEO_INPUT_CH);
00289     if (error != DisplayBase::GRAPHICS_OK) {
00290         printf("Line %d, error %d\n", __LINE__, error);
00291         while (1);
00292     }
00293 
00294     /* Video write process stop */
00295     error = Display.Video_Stop (VIDEO_INPUT_CH);
00296     if (error != DisplayBase::GRAPHICS_OK) {
00297         printf("Line %d, error %d\n", __LINE__, error);
00298         while (1);
00299     }
00300 
00301     /* Video write process start */
00302     error = Display.Video_Start (VIDEO_INPUT_CH);
00303     if (error != DisplayBase::GRAPHICS_OK) {
00304         printf("Line %d, error %d\n", __LINE__, error);
00305         while (1);
00306     }
00307 
00308     /* Wait vsync to update resister */
00309     WaitVsync(1);
00310 }
00311 
00312 static int snapshot_req(const char ** pp_data) {
00313     int encode_size;
00314 
00315     while ((jcu_encoding == 1) || (image_change == 0)) {
00316         Thread::wait(1);
00317     }
00318     jcu_buf_index_read = jcu_buf_index_write_done;
00319     image_change = 0;
00320 
00321     *pp_data = (const char *)JpegBuffer[jcu_buf_index_read];
00322     encode_size = (int)jcu_encode_size[jcu_buf_index_read];
00323 
00324     return encode_size;
00325 }
00326 
00327 static void TerminalWrite(Arguments* arg, Reply* r) {
00328     printf("%s\n",arg->argv[0]);
00329 }
00330 
00331 static void mount_romramfs(void) {
00332     FILE * fp;
00333 
00334     romramfs.format();
00335 
00336     //index.htm
00337     fp = fopen("/romram/index.htm", "w");
00338     fwrite(index_htm_tbl, sizeof(char), sizeof(index_htm_tbl), fp);
00339     fclose(fp);
00340 
00341     //camera.js
00342     fp = fopen("/romram/camera.js", "w");
00343     fwrite(camaera_js_tbl, sizeof(char), sizeof(camaera_js_tbl), fp);
00344     fclose(fp);
00345 
00346     //camera.htm
00347     fp = fopen("/romram/camera.htm", "w");
00348     fwrite(camera_htm_tbl, sizeof(char), sizeof(camera_htm_tbl), fp);
00349     fclose(fp);
00350 
00351     //mbedrpc.js
00352     fp = fopen("/romram/mbedrpc.js", "w");
00353     fwrite(mbedrpc_js_tbl, sizeof(char), sizeof(mbedrpc_js_tbl), fp);
00354     fclose(fp);
00355 
00356     //led.htm
00357     fp = fopen("/romram/led.htm", "w");
00358     fwrite(led_htm_tbl, sizeof(char), sizeof(led_htm_tbl), fp);
00359     fclose(fp);
00360 
00361     //i2c_set.htm
00362     fp = fopen("/romram/i2c_set.htm", "w");
00363     fwrite(i2c_set_htm_tbl, sizeof(char), sizeof(i2c_set_htm_tbl), fp);
00364     fclose(fp);
00365 
00366     //web_top.htm
00367     fp = fopen("/romram/web_top.htm", "w");
00368     fwrite(web_top_htm_tbl, sizeof(char), sizeof(web_top_htm_tbl), fp);
00369     fclose(fp);
00370 
00371     //menu.htm
00372     fp = fopen("/romram/menu.htm", "w");
00373     fwrite(menu_htm_tbl, sizeof(char), sizeof(menu_htm_tbl), fp);
00374     fclose(fp);
00375 
00376     //window.htm
00377     fp = fopen("/romram/window.htm", "w");
00378     fwrite(window_htm_tbl, sizeof(char), sizeof(window_htm_tbl), fp);
00379     fclose(fp);
00380 }
00381 
00382 static void SetI2CfromWeb(Arguments* arg, Reply* r) {
00383     int result = 0;
00384 
00385     if (arg != NULL) {
00386         if (arg->argc >= 2) {
00387             if ((arg->argv[0] != NULL) && (arg->argv[1] != NULL)) {
00388                 sprintf(i2c_setting_str_buf, "%s,%s", arg->argv[0], arg->argv[1]);
00389                 result = 1;
00390             }
00391         } else if (arg->argc == 1) {
00392             if (arg->argv[0] != NULL) {
00393                 sprintf(i2c_setting_str_buf, "%s", arg->argv[0]);
00394                 result = 1;
00395             }
00396         } else {
00397             /* Do nothing */
00398         }
00399         /* command analysis and execute */
00400         if (result != 0) {
00401             if (i2c_setting_exe(i2c_setting_str_buf) != false) {
00402                 r->putData<const char*>(i2c_setting_str_buf);
00403             }
00404         }
00405     }
00406 }
00407 
00408 int main(void) {
00409     printf("********* PROGRAM START ***********\r\n");
00410 
00411     /* Please enable this line when performing the setting from the Terminal side. */
00412 //    Thread thread(SetI2CfromTerm, NULL, osPriorityBelowNormal, DEFAULT_STACK_SIZE);
00413 
00414     mount_romramfs();   //RomRamFileSystem Mount
00415     camera_start();     //Camera Start
00416 
00417     RPC::add_rpc_class<RpcDigitalOut>();
00418     RPC::construct<RpcDigitalOut, PinName, const char*>(LED1, "led1");
00419     RPC::construct<RpcDigitalOut, PinName, const char*>(LED2, "led2");
00420     RPC::construct<RpcDigitalOut, PinName, const char*>(LED3, "led3");
00421     RPCFunction rpcFunc(TerminalWrite, "TerminalWrite");
00422     RPCFunction rpcSetI2C(SetI2CfromWeb, "SetI2CfromWeb");
00423 
00424     printf("Network Setting up...\r\n");
00425 #if (USE_DHCP == 1)
00426     if (network.init() != 0) {                             //for DHCP Server
00427 #else
00428     if (network.init(IP_ADDRESS, SUBNET_MASK, DEFAULT_GATEWAY) != 0) { //for Static IP Address (IPAddress, NetMasks, Gateway)
00429 #endif
00430         printf("Network Initialize Error \r\n");
00431         return -1;
00432     }
00433     if (network.connect() != 0) {
00434         printf("Network Connect Error \r\n");
00435         return -1;
00436     }
00437     printf("MAC Address is %s\r\n", network.getMACAddress());
00438     printf("IP Address is %s\r\n", network.getIPAddress());
00439     printf("NetMask is %s\r\n", network.getNetworkMask());
00440     printf("Gateway Address is %s\r\n", network.getGateway());
00441     printf("Network Setup OK\r\n");
00442 
00443     SnapshotHandler::attach_req(&snapshot_req);
00444     HTTPServerAddHandler<SnapshotHandler>("/camera"); //Camera
00445     FSHandler::mount("/romram", "/");
00446     HTTPServerAddHandler<FSHandler>("/");
00447     HTTPServerAddHandler<RPCHandler>("/rpc");
00448     HTTPServerStart(80);
00449 }