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.
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
Generated on Tue Jul 12 2022 22:22:37 by
1.7.2