Port of TI's CC3100 Websock camera demo. Using FreeRTOS, mbedTLS, also parts of Arducam for cams ov5642 and 0v2640. Can also use MT9D111. Work in progress. Be warned some parts maybe a bit flacky. This is for Seeed Arch max only, for an M3, see the demo for CM3 using the 0v5642 aducam mini.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers camera_app.cpp Source File

camera_app.cpp

00001 //*****************************************************************************
00002 // camera_app.c
00003 //
00004 // camera application macro & APIs
00005 //
00006 // Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
00007 //
00008 //
00009 //  Redistribution and use in source and binary forms, with or without
00010 //  modification, are permitted provided that the following conditions
00011 //  are met:
00012 //
00013 //    Redistributions of source code must retain the above copyright
00014 //    notice, this list of conditions and the following disclaimer.
00015 //
00016 //    Redistributions in binary form must reproduce the above copyright
00017 //    notice, this list of conditions and the following disclaimer in the
00018 //    documentation and/or other materials provided with the
00019 //    distribution.
00020 //
00021 //    Neither the name of Texas Instruments Incorporated nor the names of
00022 //    its contributors may be used to endorse or promote products derived
00023 //    from this software without specific prior written permission.
00024 //
00025 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00026 //  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00027 //  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00028 //  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00029 //  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00030 //  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00031 //  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00032 //  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00033 //  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00034 //  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00035 //  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 //*****************************************************************************
00038 //*****************************************************************************
00039 //
00040 //! \addtogroup camera_app
00041 //! @{
00042 //
00043 //*****************************************************************************
00044 #include "mbed.h"
00045 #include <stdio.h>
00046 #include <string.h>
00047 #include <stdlib.h>
00048 
00049 // SimpleLink include
00050 #include "cc3100_simplelink.h"
00051 
00052 #include "oslib/osi.h"
00053 #include "app_config.h"
00054 #include "camera_app.h"
00055 #include "mt9d111.h"
00056 #ifdef OV5642_CAM
00057 #include "ov5642.h"
00058 #endif
00059 #ifdef OV2640_CAM
00060 #include "ov2640.h"
00061 #include "ov5642.h"
00062 #endif
00063 #include "i2cconfig.h"
00064 
00065 #include "cli_uart.h"
00066 #include "Led_config.h"
00067 #include "HttpDebug.h"
00068 
00069 using namespace mbed_cc3100;
00070 
00071 
00072 
00073 //*****************************************************************************
00074 // Macros
00075 //*****************************************************************************
00076 #define USER_FILE_NAME          "www/images/cc3200_camera_capture.jpg"
00077 #define AP_SSID_LEN_MAX         (33)
00078 #define ROLE_INVALID            (-5)
00079 //*****************************************************************************
00080 //                      GLOBAL VARIABLES
00081 //*****************************************************************************
00082 
00083 unsigned int g_frame_size_in_bytes;
00084 extern volatile unsigned char g_CaptureImage;
00085 extern int g_uiIpObtained = 0;
00086 extern int g_uiSimplelinkRole = ROLE_INVALID;
00087 unsigned int g_uiIpAddress = 0;
00088 uint32_t picLoop = 0;
00089 volatile static unsigned char g_frame_end;
00090 volatile static uint16_t g_lines;
00091 
00092 
00093 DCMI_HandleTypeDef phdcmi;
00094 DMA_HandleTypeDef phdma_dcmi;
00095 
00096 #ifdef ENABLE_JPEG
00097 int PIXELS_IN_X_AXIS = 320;
00098 int PIXELS_IN_Y_AXIS = 240;
00099 int FRAME_SIZE_IN_BYTES = (320 * 240 * 2);
00100 #else
00101 int PIXELS_IN_X_AXIS = 176;
00102 int PIXELS_IN_Y_AXIS = 144;
00103 int FRAME_SIZE_IN_BYTES = (176 * 144 * 2);
00104 #endif
00105 
00106 struct ImageBuffer {
00107 #ifdef ENABLE_JPEG
00108     char g_header[SMTP_BUF_LEN] /*= {'\0'}*/;
00109 #endif
00110     uint32_t g_image_buffer[((IMAGE_BUF_SIZE)/(sizeof(unsigned int)))];//25Kb
00111     uint8_t sec_image_buffer[26 * 1024];
00112 };
00113 
00114 ImageBuffer g_image;
00115 
00116 typedef enum pictureRequest {
00117     NO_PICTURE = 0x00,
00118     SINGLE_HIGH_RESOLUTION = 0x01,
00119     STREAM_LOW_RESOLUTION = 0x02
00120 
00121 } e_pictureRequest;
00122 
00123 typedef enum pictureFormat {
00124     RAW_10BIT = 0,
00125     ITU_R_BT601,
00126     YCbCr_4_2_2,
00127     YCbCr_4_2_0,
00128     RGB_565,
00129     RGB_555,
00130     RGB_444
00131 
00132 } e_pictureFormat;
00133 
00134 typedef enum pictureResolution {
00135     QVGA = 0,
00136     VGA,
00137     SVGA,
00138     XGA,
00139     uXGA
00140 
00141 } e_pictureResolution;
00142 
00143 
00144 #ifdef ENABLE_JPEG
00145 #define FORMAT_YCBCR422   0
00146 #define FORMAT_YCBCR420   1
00147 #define FORMAT_MONOCHROME 2
00148 
00149 unsigned char JPEG_StdQuantTblY[64] = {
00150     16,  11,  10,  16,  24,  40,  51,  61,
00151     12,  12,  14,  19,  26,  58,  60,  55,
00152     14,  13,  16,  24,  40,  57,  69,  56,
00153     14,  17,  22,  29,  51,  87,  80,  62,
00154     18,  22,  37,  56,  68,  109, 103, 77,
00155     24,  35,  55,  64,  81,  104, 113, 92,
00156     49,  64,  78,  87, 103,  121, 120, 101,
00157     72,  92,  95,  98, 112,  100, 103,  99
00158 };
00159 
00160 unsigned char JPEG_StdQuantTblC[64] = {
00161     17,  18,  24,  47,  99,  99,  99,  99,
00162     18,  21,  26,  66,  99,  99,  99,  99,
00163     24,  26,  56,  99,  99,  99,  99,  99,
00164     47,  66,  99,  99,  99,  99,  99,  99,
00165     99,  99,  99,  99,  99,  99,  99,  99,
00166     99,  99,  99,  99,  99,  99,  99,  99,
00167     99,  99,  99,  99,  99,  99,  99,  99,
00168     99,  99,  99,  99,  99,  99,  99,  99
00169 };
00170 //
00171 // This table is used for regular-position to zigzagged-position lookup
00172 //  This is Figure A.6 from the ISO/IEC 10918-1 1993 specification
00173 //
00174 static unsigned char zigzag[64] = {
00175     0, 1, 5, 6,14,15,27,28,
00176     2, 4, 7,13,16,26,29,42,
00177     3, 8,12,17,25,30,41,43,
00178     9,11,18,24,31,40,44,53,
00179     10,19,23,32,39,45,52,54,
00180     20,22,33,38,46,51,55,60,
00181     21,34,37,47,50,56,59,61,
00182     35,36,48,49,57,58,62,63
00183 };
00184 
00185 unsigned int JPEG_StdHuffmanTbl[384] = {
00186     0x100, 0x101, 0x204, 0x30b, 0x41a, 0x678, 0x7f8, 0x9f6,
00187     0xf82, 0xf83, 0x30c, 0x41b, 0x679, 0x8f6, 0xaf6, 0xf84,
00188     0xf85, 0xf86, 0xf87, 0xf88, 0x41c, 0x7f9, 0x9f7, 0xbf4,
00189     0xf89, 0xf8a, 0xf8b, 0xf8c, 0xf8d, 0xf8e, 0x53a, 0x8f7,
00190     0xbf5, 0xf8f, 0xf90, 0xf91, 0xf92, 0xf93, 0xf94, 0xf95,
00191     0x53b, 0x9f8, 0xf96, 0xf97, 0xf98, 0xf99, 0xf9a, 0xf9b,
00192     0xf9c, 0xf9d, 0x67a, 0xaf7, 0xf9e, 0xf9f, 0xfa0, 0xfa1,
00193     0xfa2, 0xfa3, 0xfa4, 0xfa5, 0x67b, 0xbf6, 0xfa6, 0xfa7,
00194     0xfa8, 0xfa9, 0xfaa, 0xfab, 0xfac, 0xfad, 0x7fa, 0xbf7,
00195     0xfae, 0xfaf, 0xfb0, 0xfb1, 0xfb2, 0xfb3, 0xfb4, 0xfb5,
00196     0x8f8, 0xec0, 0xfb6, 0xfb7, 0xfb8, 0xfb9, 0xfba, 0xfbb,
00197     0xfbc, 0xfbd, 0x8f9, 0xfbe, 0xfbf, 0xfc0, 0xfc1, 0xfc2,
00198     0xfc3, 0xfc4, 0xfc5, 0xfc6, 0x8fa, 0xfc7, 0xfc8, 0xfc9,
00199     0xfca, 0xfcb, 0xfcc, 0xfcd, 0xfce, 0xfcf, 0x9f9, 0xfd0,
00200     0xfd1, 0xfd2, 0xfd3, 0xfd4, 0xfd5, 0xfd6, 0xfd7, 0xfd8,
00201     0x9fa, 0xfd9, 0xfda, 0xfdb, 0xfdc, 0xfdd, 0xfde, 0xfdf,
00202     0xfe0, 0xfe1, 0xaf8, 0xfe2, 0xfe3, 0xfe4, 0xfe5, 0xfe6,
00203     0xfe7, 0xfe8, 0xfe9, 0xfea, 0xfeb, 0xfec, 0xfed, 0xfee,
00204     0xfef, 0xff0, 0xff1, 0xff2, 0xff3, 0xff4, 0xff5, 0xff6,
00205     0xff7, 0xff8, 0xff9, 0xffa, 0xffb, 0xffc, 0xffd, 0xffe,
00206     0x30a, 0xaf9, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
00207     0xfd0, 0xfd1, 0xfd2, 0xfd3, 0xfd4, 0xfd5, 0xfd6, 0xfd7,
00208     0x101, 0x204, 0x30a, 0x418, 0x419, 0x538, 0x678, 0x8f4,
00209     0x9f6, 0xbf4, 0x30b, 0x539, 0x7f6, 0x8f5, 0xaf6, 0xbf5,
00210     0xf88, 0xf89, 0xf8a, 0xf8b, 0x41a, 0x7f7, 0x9f7, 0xbf6,
00211     0xec2, 0xf8c, 0xf8d, 0xf8e, 0xf8f, 0xf90, 0x41b, 0x7f8,
00212     0x9f8, 0xbf7, 0xf91, 0xf92, 0xf93, 0xf94, 0xf95, 0xf96,
00213     0x53a, 0x8f6, 0xf97, 0xf98, 0xf99, 0xf9a, 0xf9b, 0xf9c,
00214     0xf9d, 0xf9e, 0x53b, 0x9f9, 0xf9f, 0xfa0, 0xfa1, 0xfa2,
00215     0xfa3, 0xfa4, 0xfa5, 0xfa6, 0x679, 0xaf7, 0xfa7, 0xfa8,
00216     0xfa9, 0xfaa, 0xfab, 0xfac, 0xfad, 0xfae, 0x67a, 0xaf8,
00217     0xfaf, 0xfb0, 0xfb1, 0xfb2, 0xfb3, 0xfb4, 0xfb5, 0xfb6,
00218     0x7f9, 0xfb7, 0xfb8, 0xfb9, 0xfba, 0xfbb, 0xfbc, 0xfbd,
00219     0xfbe, 0xfbf, 0x8f7, 0xfc0, 0xfc1, 0xfc2, 0xfc3, 0xfc4,
00220     0xfc5, 0xfc6, 0xfc7, 0xfc8, 0x8f8, 0xfc9, 0xfca, 0xfcb,
00221     0xfcc, 0xfcd, 0xfce, 0xfcf, 0xfd0, 0xfd1, 0x8f9, 0xfd2,
00222     0xfd3, 0xfd4, 0xfd5, 0xfd6, 0xfd7, 0xfd8, 0xfd9, 0xfda,
00223     0x8fa, 0xfdb, 0xfdc, 0xfdd, 0xfde, 0xfdf, 0xfe0, 0xfe1,
00224     0xfe2, 0xfe3, 0xaf9, 0xfe4, 0xfe5, 0xfe6, 0xfe7, 0xfe8,
00225     0xfe9, 0xfea, 0xfeb, 0xfec, 0xde0, 0xfed, 0xfee, 0xfef,
00226     0xff0, 0xff1, 0xff2, 0xff3, 0xff4, 0xff5, 0xec3, 0xff6,
00227     0xff7, 0xff8, 0xff9, 0xffa, 0xffb, 0xffc, 0xffd, 0xffe,
00228     0x100, 0x9fa, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
00229     0xfd0, 0xfd1, 0xfd2, 0xfd3, 0xfd4, 0xfd5, 0xfd6, 0xfd7,
00230     0x100, 0x202, 0x203, 0x204, 0x205, 0x206, 0x30e, 0x41e,
00231     0x53e, 0x67e, 0x7fe, 0x8fe, 0xfff, 0xfff, 0xfff, 0xfff,
00232     0x100, 0x101, 0x102, 0x206, 0x30e, 0x41e, 0x53e, 0x67e,
00233     0x7fe, 0x8fe, 0x9fe, 0xafe, 0xfff, 0xfff, 0xfff, 0xfff
00234 };
00235 #endif
00236 
00237 //*****************************************************************************
00238 //
00239 //!     Start Camera
00240 //!     1. Establishes connection w/ AP//
00241 //!     2. Initializes the camera sub-components//! GPIO Enable & Configuration
00242 //!     3. Listens and processes the image capture requests from user-applications
00243 //!
00244 //! \param[out]                      WriteBuffer - Pointer to the Frame Buffer
00245 //!     \return                     None
00246 //
00247 //*****************************************************************************
00248 
00249 uint32_t StartCamera(char **WriteBuffer)
00250 {
00251     uint32_t Writelength;
00252     //
00253     // Waits in the below loop till Capture button is pressed
00254     //
00255     Writelength = CaptureImage(WriteBuffer);
00256 
00257     return(Writelength);
00258 
00259 }
00260 //*****************************************************************************
00261 //
00262 //!     InitCameraComponents
00263 //!     PinMux, Camera Initialization and Configuration
00264 //!
00265 //! \param[in] width - X-Axis
00266 //! \param[in] width - Y-Axis
00267 //! \return  None
00268 //
00269 //*****************************************************************************
00270 
00271 void InitCameraComponents(int width, int height)
00272 {
00273     Uart_Write((uint8_t*)"InitCameraComponents \n\r");
00274     //
00275     // Initialize I2C Interface
00276     //
00277     I2CInit();
00278 #ifdef MT9D111_CAM
00279     cam_power_on();    
00280     getCamId();
00281     
00282     //
00283     // Initialize camera sensor
00284     //
00285     CameraSensorInit();
00286 #ifdef ENABLE_JPEG
00287     //
00288     // Configure Sensor in Capture Mode
00289     //
00290     PIXELS_IN_X_AXIS = width;
00291     PIXELS_IN_Y_AXIS = height;
00292     FRAME_SIZE_IN_BYTES = PIXELS_IN_X_AXIS * PIXELS_IN_Y_AXIS * BYTES_PER_PIXEL;
00293 
00294     StartSensorInJpegMode(width, height);
00295 
00296 #endif//ENABLE_JPEG
00297 #endif//MT9D111_CAM    
00298     
00299 #ifdef OV5642_CAM
00300     check_camId();
00301     init_cam();    
00302 #endif//OV5642_CAM
00303 
00304 #ifdef OV2640_CAM
00305     camId();
00306     initCam();    
00307 #endif//OV2640_CAM
00308 
00309     
00310     
00311 }
00312 
00313 //*****************************************************************************
00314 //
00315 //!     Set resolution of camera
00316 //!
00317 //! \param[in] width - X Axis
00318 //! \param[in] height - Y Axis
00319 //! \return  0 on success else -ve
00320 //
00321 //*****************************************************************************
00322 
00323 int SetCameraResolution(int width, int height)
00324 {
00325     Uart_Write((uint8_t*)"SetCameraResolution \n\r");
00326     int lRetVal = 0;
00327 
00328     PIXELS_IN_X_AXIS = width;
00329     PIXELS_IN_Y_AXIS = height;
00330     FRAME_SIZE_IN_BYTES = PIXELS_IN_X_AXIS * PIXELS_IN_Y_AXIS * BYTES_PER_PIXEL;
00331     lRetVal = CameraSensorResolution(width, height);
00332     return lRetVal;
00333 }
00334 
00335 //*****************************************************************************
00336 //
00337 //!     CaptureImage
00338 //!     Configures DMA and starts the Capture. Post Capture writes to SFLASH
00339 //!
00340 //! \param                      None
00341 //!     \return                     None
00342 //!
00343 //
00344 //*****************************************************************************
00345 uint32_t CaptureImage(char** WriteBuffer)
00346 {
00347 
00348     uint32_t g_header_length = 0;
00349     uint32_t image_size = 0;
00350     uint32_t *pbuffer = &(g_image.g_image_buffer[0]);
00351     uint8_t *sec_pbuffer = &(g_image.sec_image_buffer[0]);
00352 //    int32_t lRetVal= -1;
00353     int32_t err = 0;
00354 #ifdef MT9D111_CAM     
00355     uint8_t jpeg_end[] = {0xFF, 0xD9};
00356 #endif
00357     picLoop++;    
00358     DMAConfig();
00359     
00360 //    wait(1);
00361 #ifdef MT9D111_CAM    
00362     /* Send cam capture request, value in frames */
00363     Start_still_capture(1);// Switch to context b
00364     wait(1);
00365 #endif
00366     //
00367     // DCMI Perform Image Capture
00368     //
00369 #ifdef ENABLE_JPEG
00370     HAL_DCMI_Start_DMA(&phdcmi, DCMI_MODE_SNAPSHOT, (uint32_t)pbuffer, NUM_OF_4B_CHUNKS);
00371 #else
00372     HAL_DCMI_Start_DMA(&phdcmi, DCMI_MODE_CONTINUOUS, (uint32_t)pbuffer, NUM_OF_4B_CHUNKS);
00373 #endif
00374 
00375     while(g_frame_end == 0);//Set in the Frame complete callback function 
00376 
00377 #ifdef MT9D111_CAM    
00378     Stop_still_capture();// Switch to context a
00379 #endif    
00380     /* Read the number of data items transferred in bytes ((4x) uint = bytes) */
00381     g_frame_size_in_bytes = 4*(NUM_OF_4B_CHUNKS - phdma_dcmi.Instance->NDTR);//NDTR counts down!
00382     if(g_frame_size_in_bytes <= 0 || g_frame_size_in_bytes > (NUM_OF_4B_CHUNKS *4)) {
00383         err = HAL_DMA_GetState(&phdma_dcmi);
00384         HttpDebug("\r\nDMA error! 0x%x\r\n",err);
00385         HttpDebug("\r\nDMA error! 0x%x\r\n",phdma_dcmi.ErrorCode);
00386         HttpDebug("g_frame_size_in_bytes = 0x%x\r\n",g_frame_size_in_bytes);
00387         HttpDebug("\r\nFailed to capture data, check camera connections!\r\n");
00388         HAL_DMA_Abort(&phdma_dcmi);
00389 #ifdef MT9D111_CAM        
00390         cam_power_off();
00391 #endif        
00392         HAL_DCMI_MspDeInit (&phdcmi);
00393         HttpDebug("Image Capture failed\n\r");
00394         while(1) {
00395             wait(0.5);
00396         }
00397     } 
00398     
00399     uint8_t* Image = reinterpret_cast<uint8_t*>(pbuffer);
00400     
00401 #ifdef MT9D111_CAM
00402     memcpy(Image + g_frame_size_in_bytes, jpeg_end, 2);
00403     g_frame_size_in_bytes += 2;
00404 #endif
00405         
00406     //
00407     // Create JPEG Header
00408     //
00409 #ifdef MT9D111_CAM    
00410 #ifdef ENABLE_JPEG
00411     memset(g_image.g_header, '\0', sizeof(g_image.g_header));
00412     g_header_length = CreateJpegHeader((char *)&(g_image.g_header[0]), PIXELS_IN_X_AXIS, PIXELS_IN_Y_AXIS, 0, 0x0020, 8);
00413 
00414     // This pushes the header to the start of the array so that the entire picture can be contiguous in memory    
00415     memcpy(sec_pbuffer + g_header_length, Image, g_frame_size_in_bytes);
00416     memcpy(sec_pbuffer, g_image.g_header, g_header_length);
00417 
00418     image_size = g_header_length + g_frame_size_in_bytes;  
00419     HttpDebug("\r\nCapture Image %d size 0x%x\r\n",picLoop, image_size); 
00420 #endif//ENABLE_JPEG
00421     *WriteBuffer = (char*)g_image.sec_image_buffer;
00422     return(g_header_length += g_frame_size_in_bytes);
00423 #endif//MT9D111_CAM
00424     HttpDebug("\r\nCapture Image %d size 0x%x\r\n",picLoop, image_size);    
00425     *WriteBuffer = (char*)g_image.sec_image_buffer;
00426 
00427     return(g_frame_size_in_bytes);
00428 }
00429 //*****************************************************************************
00430 //
00431 //!     DMA Config
00432 //!     Initialize the DMA\DCMI and Setup the DMA transfer
00433 //!
00434 //! \param                      None
00435 //!     \return                     None
00436 //
00437 //*****************************************************************************
00438 void DMAConfig()
00439 {
00440 
00441     phdcmi.Init.SynchroMode      = DCMI_SYNCHRO_HARDWARE;
00442 #ifdef OV5642_CAM       
00443     phdcmi.Init.PCKPolarity      = DCMI_PCKPOLARITY_RISING;//Data clocked out on rising edge
00444     phdcmi.Init.VSPolarity       = DCMI_VSPOLARITY_HIGH;//Active high
00445     phdcmi.Init.HSPolarity       = DCMI_HSPOLARITY_LOW;//Active low
00446 #endif    
00447 #ifdef OV2640_CAM    
00448     phdcmi.Init.PCKPolarity      = DCMI_PCKPOLARITY_RISING;//Data clocked out on rising edge
00449     phdcmi.Init.VSPolarity       = DCMI_VSPOLARITY_LOW;//Active low
00450     phdcmi.Init.HSPolarity       = DCMI_HSPOLARITY_LOW;//Active low
00451 #endif    
00452 #ifdef MT9D111_CAM
00453     phdcmi.Init.PCKPolarity      = DCMI_PCKPOLARITY_RISING;//Data clocked out on rising edge      
00454     phdcmi.Init.VSPolarity       = DCMI_VSPOLARITY_LOW;//Active high
00455     phdcmi.Init.HSPolarity       = DCMI_HSPOLARITY_LOW;//Active high    
00456 #endif        
00457     phdcmi.Init.CaptureRate      = DCMI_CR_ALL_FRAME;
00458     phdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;//8 bit data
00459 #ifdef ENABLE_JPEG
00460     phdcmi.Init.JPEGMode         = DCMI_JPEG_ENABLE;
00461 #else
00462     phdcmi.Init.JPEGMode         = DCMI_JPEG_DISABLE;
00463 #endif
00464     phdcmi.Instance              = DCMI;
00465 
00466     DCMI_MspInit (&phdcmi);
00467     HAL_DCMI_Init(&phdcmi);
00468      
00469 }
00470 
00471 void DCMI_MspInit (DCMI_HandleTypeDef* hdcmi)
00472 {
00473 
00474     /* Peripheral DCMI init*/
00475 
00476     GPIO_InitTypeDef GPIO_InitStruct;
00477     if(hdcmi->Instance==DCMI) {
00478         __GPIOA_CLK_ENABLE();
00479         __GPIOB_CLK_ENABLE();
00480         __GPIOC_CLK_ENABLE();
00481         __GPIOE_CLK_ENABLE();
00482 
00483         /* Peripheral clock enable */
00484         __DCMI_CLK_ENABLE();
00485         /* DMA controller clock enable */
00486         __DMA2_CLK_ENABLE();
00487 
00488         /**MCO1 GPIO Configuration
00489         PA8     ------> RCC_MCO_1
00490         */
00491 
00492         /**DCMI GPIO Configuration
00493         PA9     ------> DCMI_D0
00494         PA10    ------> DCMI_D1
00495         PC8     ------> DCMI_D2
00496         PC9     ------> DCMI_D3
00497         PE4     ------> DCMI_D4
00498         PB6     ------> DCMI_D5
00499         PE5     ------> DCMI_D6
00500         PE6     ------> DCMI_D7
00501         PA6     ------> DCMI_PIXCK
00502         PA4     ------> DCMI_HSYNC
00503         PB7     ------> DCMI_VSYNC
00504 
00505         */
00506         /* D4 D6 D7 */
00507         GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
00508         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
00509         GPIO_InitStruct.Pull = GPIO_PULLUP;
00510         GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
00511         GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
00512         HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
00513 
00514         /* HSYNC PIXCLK D0 D1 */
00515         GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_9|GPIO_PIN_10;
00516         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
00517         GPIO_InitStruct.Pull = GPIO_PULLUP;
00518         GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
00519         GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
00520         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
00521 
00522         /* D2 D3 */
00523         GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
00524         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
00525         GPIO_InitStruct.Pull = GPIO_PULLUP;
00526         GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
00527         GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
00528         HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
00529 
00530         /* D5 VSYNC */
00531         GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
00532         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
00533         GPIO_InitStruct.Pull = GPIO_PULLUP;
00534         GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
00535         GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
00536         HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
00537 
00538         phdma_dcmi.Instance                 = DMA2_Stream1;
00539         phdma_dcmi.Init.Channel             = DMA_CHANNEL_1;
00540         phdma_dcmi.Init.Direction           = DMA_PERIPH_TO_MEMORY;
00541         phdma_dcmi.Init.PeriphInc           = DMA_PINC_DISABLE;
00542         phdma_dcmi.Init.MemInc              = DMA_MINC_ENABLE;
00543         phdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;//Cam is 1 byte wide data (8 bits) should this be word?????
00544         phdma_dcmi.Init.MemDataAlignment    = DMA_PDATAALIGN_WORD;//Memory has been defined as uint (1 word)
00545         phdma_dcmi.Init.Mode                = DMA_NORMAL;
00546         phdma_dcmi.Init.Priority            = DMA_PRIORITY_HIGH;
00547         phdma_dcmi.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
00548         phdma_dcmi.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
00549         phdma_dcmi.Init.MemBurst            = DMA_MBURST_SINGLE;
00550         phdma_dcmi.Init.PeriphBurst         = DMA_PBURST_SINGLE;
00551 
00552         __HAL_LINKDMA(hdcmi, DMA_Handle, phdma_dcmi);
00553 
00554         /*** Configure the NVIC for DCMI and DMA ***/
00555         /* NVIC configuration for DCMI transfer complete interrupt */
00556         HAL_NVIC_SetPriority(DCMI_IRQn, 3, 0);
00557         HAL_NVIC_EnableIRQ(DCMI_IRQn);
00558 
00559         /* NVIC configuration for DMA2 transfer complete interrupt */
00560         HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 3, 0);
00561         HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
00562 
00563         HAL_DMA_Init(&phdma_dcmi);
00564     }
00565 
00566     g_frame_size_in_bytes = 0;
00567     g_frame_end = 0;
00568 }
00569 
00570 /******************************************************************************/
00571 /* STM32F4xx Peripheral Interrupt Handlers                                    */
00572 /* Add here the Interrupt Handlers for the used peripherals.                  */
00573 /* For the available peripheral interrupt handler names,                      */
00574 /* please refer to the startup file (startup_stm32f4xx.s).                    */
00575 /******************************************************************************/
00576 
00577 void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi)
00578 {
00579     int32_t dcmi_state;
00580     int32_t dcmi_error;
00581     
00582     HAL_DMA_Abort(&phdma_dcmi);
00583     
00584     HttpDebug("\r\nDCMI_ErrorCallback!\r\n");
00585     
00586     dcmi_state = HAL_DCMI_GetState(&phdcmi);
00587     if(0 == dcmi_state){
00588         HttpDebug("\r\nDCMI not yet initialized or disabled\r\n");
00589     }else if(1 == dcmi_state){
00590         HttpDebug("\r\nDCMI initialized and ready for use\r\n");
00591     }else if(2 == dcmi_state){
00592         HttpDebug("\r\nDCMI internal processing is ongoing\r\n");
00593     }else if(3 == dcmi_state){
00594         HttpDebug("\r\nDCMI timeout state\r\n");
00595     }else if(4 == dcmi_state){  
00596         HttpDebug("\r\nDCMI error state\r\n");
00597         dcmi_error = HAL_DCMI_GetError(&phdcmi);
00598         if(1 == dcmi_error){
00599             HttpDebug("\r\nDCMI Synchronisation error\r\n");
00600         }else if(2 == dcmi_error){
00601             HttpDebug("\r\nDCMI Overrun\r\n");
00602         }       
00603     }               
00604     HttpDebug("\r\nExtra info! \r\n");
00605     g_frame_size_in_bytes = 4*(NUM_OF_4B_CHUNKS - phdma_dcmi.Instance->NDTR);//NDTR counts down!
00606     if(g_frame_size_in_bytes >= 0xC800){
00607         HttpDebug("Bytes captured equals or exceeds buffer size! \r\n");
00608         HttpDebug("Bytes captured 0x%x\r\n",g_frame_size_in_bytes);
00609     }else{  
00610         HttpDebug("Bytes captured 0x%x\r\n",g_frame_size_in_bytes);
00611     }
00612     
00613     HAL_DMA_Abort(&phdma_dcmi);
00614 #ifdef MT9D111_CAM    
00615     cam_power_off();
00616 #endif    
00617     HAL_DCMI_MspDeInit (&phdcmi);    
00618 }
00619 
00620 void HAL_DCMI_LineEventCallback(DCMI_HandleTypeDef *hdcmi)
00621 {
00622     //g_lines++;
00623 
00624 }
00625 
00626 void HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef *hdcmi)
00627 {
00628     //g_lines = 0;
00629 
00630 }
00631 
00632 void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
00633 {
00634     HAL_DMA_Abort(&phdma_dcmi);
00635     g_frame_end = 1;
00636     
00637     //HttpDebug("\r\nDCMI Frame Capture complete! \r\n");
00638 
00639 }
00640 
00641 void HAL_DCMI_MspDeInit (DCMI_HandleTypeDef* hdcmi)
00642 {
00643     if(hdcmi->Instance==DCMI) {
00644 
00645         /* Peripheral clock disable */
00646         __DCMI_CLK_DISABLE();
00647 
00648         /**DCMI GPIO Configuration
00649         PE4     ------> DCMI_D4
00650         PE5     ------> DCMI_D6
00651         PE6     ------> DCMI_D7
00652         PA4     ------> DCMI_HSYNC
00653         PA6     ------> DCMI_PIXCK
00654         PC8     ------> DCMI_D2
00655         PC9     ------> DCMI_D3
00656         PA9     ------> DCMI_D0
00657         PA10    ------> DCMI_D1
00658         PB6     ------> DCMI_D5
00659         PB7     ------> DCMI_VSYNC
00660 
00661         PA8     ------> MCO1
00662         */
00663 
00664         HAL_GPIO_DeInit(GPIOE, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6);
00665 
00666         HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10);
00667 
00668         HAL_GPIO_DeInit(GPIOC, GPIO_PIN_9|GPIO_PIN_8);
00669 
00670         HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
00671 
00672         /* Peripheral DMA DeInit*/
00673         HAL_DMA_DeInit(hdcmi->DMA_Handle);
00674 
00675         /* Peripheral interrupt DeInit*/
00676         HAL_NVIC_DisableIRQ(DCMI_IRQn);
00677 
00678         HAL_GPIO_DeInit(GPIOA, GPIO_PIN_8);
00679         HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8 | GPIO_PIN_9);
00680     }
00681 
00682 
00683 }
00684 
00685 //*****************************************************************************
00686 //
00687 //!     JfifApp0Marker
00688 //!
00689 //! \param                      Pointer to the output buffer
00690 //!     \return                     Length of the Marker
00691 //
00692 //*****************************************************************************
00693 
00694 #ifdef ENABLE_JPEG
00695 static int JfifApp0Marker(char *pbuf)
00696 {
00697 //    Uart_Write((uint8_t*)"JfifApp0Marker \n\r");
00698     *pbuf++= 0xFF;                  // APP0 marker
00699     *pbuf++= 0xE0;
00700     *pbuf++= 0x00;                  // length
00701     *pbuf++= 0x10;
00702     *pbuf++= 0x4A;                  // JFIF identifier
00703     *pbuf++= 0x46;
00704     *pbuf++= 0x49;
00705     *pbuf++= 0x46;
00706     *pbuf++= 0x00;
00707     *pbuf++= 0x01;                  // version
00708     *pbuf++= 0x02;
00709     *pbuf++= 0x00;                  // units
00710     *pbuf++= 0x00;                  // X density
00711     *pbuf++= 0x01;
00712     *pbuf++= 0x00;                  // Y density
00713     *pbuf++= 0x01;
00714     *pbuf++= 0x00;                  // X thumbnail
00715     *pbuf++= 0x00;                  // Y thumbnail
00716     return 18;
00717 }
00718 
00719 
00720 //*****************************************************************************
00721 //
00722 //!    FrameHeaderMarker
00723 //!
00724 //! \param1                      pointer to the output buffer
00725 //! \param2                      width
00726 //! \param3                      height
00727 //! \param4                      format
00728 //!
00729 //!     \return                       Length of the header marker
00730 //
00731 //*****************************************************************************
00732 static int FrameHeaderMarker(char *pbuf, int width, int height, int format)
00733 {
00734 //    Uart_Write((uint8_t*)"FrameHeaderMarker \n\r");
00735     int length;
00736     if (format == FORMAT_MONOCHROME)
00737         length = 11;
00738     else
00739         length = 17;
00740 
00741     *pbuf++= 0xFF;                      // start of frame: baseline DCT
00742     *pbuf++= 0xC0;
00743     *pbuf++= length>>8;                 // length field
00744     *pbuf++= length&0xFF;
00745     *pbuf++= 0x08;                      // sample precision
00746     *pbuf++= height>>8;                 // number of lines
00747     *pbuf++= height&0xFF;
00748     *pbuf++= width>>8;                  // number of samples per line
00749     *pbuf++= width&0xFF;
00750 
00751     if (format == FORMAT_MONOCHROME) {  // monochrome
00752         *pbuf++= 0x01;                  // number of image components in frame
00753         *pbuf++= 0x00;                  // component identifier: Y
00754         *pbuf++= 0x11;                  // horizontal | vertical sampling factor: Y
00755         *pbuf++= 0x00;                  // quantization table selector: Y
00756     } else if (format == FORMAT_YCBCR422) { // YCbCr422
00757         *pbuf++= 0x03;                  // number of image components in frame
00758         *pbuf++= 0x00;                  // component identifier: Y
00759         *pbuf++= 0x21;                  // horizontal | vertical sampling factor: Y
00760         *pbuf++= 0x00;                  // quantization table selector: Y
00761         *pbuf++= 0x01;                  // component identifier: Cb
00762         *pbuf++= 0x11;                  // horizontal | vertical sampling factor: Cb
00763         *pbuf++= 0x01;                  // quantization table selector: Cb
00764         *pbuf++= 0x02;                  // component identifier: Cr
00765         *pbuf++= 0x11;                  // horizontal | vertical sampling factor: Cr
00766         *pbuf++= 0x01;                  // quantization table selector: Cr
00767     } else {                            // YCbCr420
00768         *pbuf++= 0x03;                  // number of image components in frame
00769         *pbuf++= 0x00;                  // component identifier: Y
00770         *pbuf++= 0x22;                  // horizontal | vertical sampling factor: Y
00771         *pbuf++= 0x00;                  // quantization table selector: Y
00772         *pbuf++= 0x01;                  // component identifier: Cb
00773         *pbuf++= 0x11;                  // horizontal | vertical sampling factor: Cb
00774         *pbuf++= 0x01;                  // quantization table selector: Cb
00775         *pbuf++= 0x02;                  // component identifier: Cr
00776         *pbuf++= 0x11;                  // horizontal | vertical sampling factor: Cr
00777         *pbuf++= 0x01;                  // quantization table selector: Cr
00778     }
00779 
00780     return (length+2);
00781 }
00782 
00783 
00784 //*****************************************************************************
00785 //
00786 //!     ScanHeaderMarker
00787 //!
00788 //! \param1                     pointer to output buffer
00789 //! \param2                     Format
00790 //!
00791 //!     \return                     Length
00792 //
00793 //*****************************************************************************
00794 static int ScanHeaderMarker(char *pbuf, int format)
00795 {
00796     int length;
00797     if (format == FORMAT_MONOCHROME)
00798         length = 8;
00799     else
00800         length = 12;
00801 
00802     *pbuf++= 0xFF;                  // start of scan
00803     *pbuf++= 0xDA;
00804     *pbuf++= length>>8;             // length field
00805     *pbuf++= length&0xFF;
00806     if (format == FORMAT_MONOCHROME) { // monochrome
00807         *pbuf++= 0x01;              // number of image components in scan
00808         *pbuf++= 0x00;              // scan component selector: Y
00809         *pbuf++= 0x00;              // DC | AC huffman table selector: Y
00810     } else {                        // YCbCr
00811         *pbuf++= 0x03;              // number of image components in scan
00812         *pbuf++= 0x00;              // scan component selector: Y
00813         *pbuf++= 0x00;              // DC | AC huffman table selector: Y
00814         *pbuf++= 0x01;              // scan component selector: Cb
00815         *pbuf++= 0x11;              // DC | AC huffman table selector: Cb
00816         *pbuf++= 0x02;              // scan component selector: Cr
00817         *pbuf++= 0x11;              // DC | AC huffman table selector: Cr
00818     }
00819 
00820     *pbuf++= 0x00;                  // Ss: start of predictor selector
00821     *pbuf++= 0x3F;                  // Se: end of spectral selector
00822     *pbuf++= 0x00;                  // Ah | Al: successive approximation bit position
00823 
00824     return (length+2);
00825 }
00826 
00827 
00828 //*****************************************************************************
00829 //
00830 //!     DefineQuantizationTableMarker
00831 //!      Calculate and write the quantisation tables
00832 //!      qscale is the customised scaling factor - see MT9D131 developer guide page 78
00833 //!
00834 //! \param1                      pointer to the output buffer
00835 //! \param2                      Quantization Scale
00836 //! \param3                      Format
00837 //!
00838 //!     \return                      Length of the Marker
00839 //
00840 //*****************************************************************************
00841 static int DefineQuantizationTableMarker (unsigned char *pbuf, int qscale, int format)
00842 {
00843 //    Uart_Write((uint8_t*)"DefineQuantizationTableMarker \n\r");
00844     int i, length, temp;
00845     unsigned char newtbl[64];           // temporary array to store scaled zigzagged quant entries
00846 
00847     if (format == FORMAT_MONOCHROME)    // monochrome
00848         length  =  67;
00849     else
00850         length  =  132;
00851 
00852     *pbuf++  =  0xFF;                   // define quantization table marker
00853     *pbuf++  =  0xDB;
00854     *pbuf++  =  length>>8;              // length field
00855     *pbuf++  =  length&0xFF;
00856     *pbuf++  =  0;                      // quantization table precision | identifier for luminance
00857 
00858     // calculate scaled zigzagged luminance quantisation table entries
00859     for (i=0; i<64; i++) {
00860         temp = (JPEG_StdQuantTblY[i] * qscale + 16) / 32;
00861         // limit the values to the valid range
00862         if (temp <= 0)
00863             temp = 1;
00864         if (temp > 255)
00865             temp = 255;
00866         newtbl[zigzag[i]] = (unsigned char) temp;
00867     }
00868 
00869     // write the resulting luminance quant table to the output buffer
00870     for (i=0; i<64; i++)
00871         *pbuf++ = newtbl[i];
00872 
00873     // if format is monochrome we're finished, otherwise continue on, to do chrominance quant table
00874     if (format == FORMAT_MONOCHROME)
00875         return (length+2);
00876 
00877     *pbuf++ = 1;                        // quantization table precision | identifier for chrominance
00878 
00879     // calculate scaled zigzagged chrominance quantisation table entries
00880     for (i=0; i<64; i++) {
00881         temp = (JPEG_StdQuantTblC[i] * qscale + 16) / 32;
00882         // limit the values to the valid range
00883         if (temp <= 0)
00884             temp = 1;
00885         if (temp > 255)
00886             temp = 255;
00887         newtbl[zigzag[i]] = (unsigned char) temp;
00888     }
00889 
00890     // write the resulting chrominance quant table to the output buffer
00891     for (i=0; i<64; i++)
00892         *pbuf++ = newtbl[i];
00893 
00894     return (length+2);
00895 }
00896 
00897 
00898 //*****************************************************************************
00899 //
00900 //!     DefineHuffmanTableMarkerDC
00901 //!
00902 //! \param1                      pointer to Marker buffer
00903 //! \param2                      Huffman table
00904 //! \param3                      Class Identifier
00905 //!
00906 //!     \return                      Length of the marker
00907 //
00908 //*****************************************************************************
00909 static int DefineHuffmanTableMarkerDC(char *pbuf, unsigned int *htable, int class_id)
00910 {
00911 //    Uart_Write((uint8_t*)"DefineHuffmanTableMarkerDC \n\r");
00912     int i, l, count;
00913     int length;
00914     char *plength;
00915 
00916     *pbuf++= 0xFF;                  // define huffman table marker
00917     *pbuf++= 0xC4;
00918     plength = pbuf;                 // place holder for length field
00919     *pbuf++;
00920     *pbuf++;
00921     *pbuf++= class_id;              // huffman table class | identifier
00922 
00923     for (l = 0; l < 16; l++) {
00924         count = 0;
00925         for (i = 0; i < 12; i++) {
00926             if ((htable[i] >> 8) == l)
00927                 count++;
00928         }
00929         *pbuf++= count;             // number of huffman codes of length l+1
00930     }
00931 
00932     length = 19;
00933     for (l = 0; l < 16; l++) {
00934         for (i = 0; i < 12; i++) {
00935             if ((htable[i] >> 8) == l) {
00936                 *pbuf++= i;         // HUFFVAL with huffman codes of length l+1
00937                 length++;
00938             }
00939         }
00940     }
00941 
00942     *plength++= length>>8;          // length field
00943     *plength = length&0xFF;
00944 
00945     return (length + 2);
00946 }
00947 
00948 
00949 //*****************************************************************************
00950 //
00951 //!     DefineHuffmanTableMarkerAC
00952 //!     1. Establishes connection w/ AP//
00953 //!     2. Initializes the camera sub-components//! GPIO Enable & Configuration
00954 //!     3. Listens and processes the image capture requests from user-applications
00955 //!
00956 //! \param1                      pointer to Marker buffer
00957 //! \param2                      Huffman table
00958 //! \param3                      Class Identifier
00959 //!
00960 //!     \return                      Length of the Marker
00961 //!
00962 //
00963 //*****************************************************************************
00964 static int DefineHuffmanTableMarkerAC(char *pbuf, unsigned int *htable, int class_id)
00965 {
00966 //    Uart_Write((uint8_t*)"DefineHuffmanTableMarkerAC \n\r");
00967     int i, l, a, b, count;
00968     char *plength;
00969     int length;
00970 
00971     *pbuf++= 0xFF;                      // define huffman table marker
00972     *pbuf++= 0xC4;
00973     plength = pbuf;                     // place holder for length field
00974     *pbuf++;
00975     *pbuf++;
00976     *pbuf++= class_id;                  // huffman table class | identifier
00977 
00978     for (l = 0; l < 16; l++) {
00979         count = 0;
00980         for (i = 0; i < 162; i++) {
00981             if ((htable[i] >> 8) == l)
00982                 count++;
00983         }
00984 
00985         *pbuf++= count;                 // number of huffman codes of length l+1
00986     }
00987 
00988     length = 19;
00989     for (l = 0; l < 16; l++) {
00990         // check EOB: 0|0
00991         if ((htable[160] >> 8) == l) {
00992             *pbuf++= 0;                 // HUFFVAL with huffman codes of length l+1
00993             length++;
00994         }
00995 
00996         // check HUFFVAL: 0|1 to E|A
00997         for (i = 0; i < 150; i++) {
00998             if ((htable[i] >> 8) == l) {
00999                 a = i/10;
01000                 b = i%10;
01001                 *pbuf++= (a<<4)|(b+1);  // HUFFVAL with huffman codes of length l+1
01002                 length++;
01003             }
01004         }
01005 
01006         // check ZRL: F|0
01007         if ((htable[161] >> 8) == l) {
01008             *pbuf++= 0xF0;              // HUFFVAL with huffman codes of length l+1
01009             length++;
01010         }
01011 
01012         // check HUFFVAL: F|1 to F|A
01013         for (i = 150; i < 160; i++) {
01014             if ((htable[i] >> 8) == l) {
01015                 a = i/10;
01016                 b = i%10;
01017                 *pbuf++= (a<<4)|(b+1);  // HUFFVAL with huffman codes of length l+1
01018                 length++;
01019             }
01020         }
01021     }
01022 
01023     *plength++= length>>8;              // length field
01024     *plength = length&0xFF;
01025     return (length + 2);
01026 }
01027 
01028 
01029 //*****************************************************************************
01030 //
01031 //!     DefineRestartIntervalMarker
01032 //!
01033 //! \param1                      pointer to Marker buffer
01034 //! \param2                      return interval
01035 //!
01036 //!     \return                      Length
01037 //
01038 //*****************************************************************************
01039 static int DefineRestartIntervalMarker(char *pbuf, int ri)
01040 {
01041 //    Uart_Write((uint8_t*)"DefineRestartIntervalMarker \n\r");
01042     *pbuf++= 0xFF;                  // define restart interval marker
01043     *pbuf++= 0xDD;
01044     *pbuf++= 0x00;                  // length
01045     *pbuf++= 0x04;
01046     *pbuf++= ri >> 8;               // restart interval
01047     *pbuf++= ri & 0xFF;
01048     return 6;
01049 }
01050 //*****************************************************************************
01051 //
01052 //!     CreateJpegHeader
01053 //!     Create JPEG Header in JFIF format
01054 //!
01055 //! \param1                     header - pointer to JPEG header buffer
01056 //! \param2                     width - image width
01057 //! \param3                     height - image height
01058 //! \param4                     format - color format (0 = YCbCr422, 1 = YCbCr420, 2 = monochrome)
01059 //! \param5                     restart_int - restart marker interval
01060 //! \param6                     qscale - quantization table scaling factor
01061 //!
01062 //!     \return                     length of JPEG header (bytes)
01063 //
01064 //*****************************************************************************
01065 
01066 static int CreateJpegHeader(char *header, int width, int height,
01067                             int format, int restart_int, int qscale)
01068 {
01069 //    Uart_Write((uint8_t*)"CreateJpegHeader \n\r");
01070     char *pbuf = header;
01071     int length;
01072 
01073     // SOI
01074     *pbuf++= 0xFF;
01075     *pbuf++= 0xD8;
01076     length = 2;
01077 
01078     // JFIF APP0
01079     length += JfifApp0Marker(pbuf);
01080 
01081     // Quantization Tables
01082     pbuf = header + length;
01083     length += DefineQuantizationTableMarker((unsigned char *)pbuf, qscale, format);
01084 
01085     // Frame Header
01086     pbuf = header + length;
01087     length += FrameHeaderMarker(pbuf, width, height, format);
01088 
01089     // Huffman Table DC 0 for Luma
01090     pbuf = header + length;
01091     length += DefineHuffmanTableMarkerDC(pbuf, &JPEG_StdHuffmanTbl[352], 0x00);
01092 
01093     // Huffman Table AC 0 for Luma
01094     pbuf = header + length;
01095     length += DefineHuffmanTableMarkerAC(pbuf, &JPEG_StdHuffmanTbl[0], 0x10);
01096 
01097     if (format != FORMAT_MONOCHROME) { // YCbCr
01098         // Huffman Table DC 1 for Chroma
01099         pbuf = header + length;
01100         length += DefineHuffmanTableMarkerDC(pbuf, &JPEG_StdHuffmanTbl[368], 0x01);
01101 
01102         // Huffman Table AC 1 for Chroma
01103         pbuf = header + length;
01104         length += DefineHuffmanTableMarkerAC(pbuf, &JPEG_StdHuffmanTbl[176], 0x11);
01105     }
01106 
01107     // Restart Interval
01108     if (restart_int > 0) {
01109         pbuf = header + length;
01110         length += DefineRestartIntervalMarker(pbuf, restart_int);
01111     }
01112 
01113     // Scan Header
01114     pbuf = header + length;
01115     length += ScanHeaderMarker(pbuf, format);
01116 
01117     return length;
01118 }
01119 #endif// jpeg defined 
01120 
01121 
01122 
01123 //*****************************************************************************
01124 //
01125 // Close the Doxygen group.
01126 //! @}
01127 //
01128 //*****************************************************************************
01129 
01130 
01131 
01132 
01133 
01134