TI's CC3100 websocket camera demo with Arducam mini ov5642 and freertos. Should work with other M3's. Work in progress test demo.

Dependencies:   mbed

Committer:
dflet
Date:
Fri Sep 11 15:38:33 2015 +0000
Revision:
1:e448e81c416f
Parent:
0:400d8e75a8d0
Removed some debud.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dflet 0:400d8e75a8d0 1 //*****************************************************************************
dflet 0:400d8e75a8d0 2 // camera_app.c
dflet 0:400d8e75a8d0 3 //
dflet 0:400d8e75a8d0 4 // camera application macro & APIs
dflet 0:400d8e75a8d0 5 //
dflet 0:400d8e75a8d0 6 // Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
dflet 0:400d8e75a8d0 7 //
dflet 0:400d8e75a8d0 8 //
dflet 0:400d8e75a8d0 9 // Redistribution and use in source and binary forms, with or without
dflet 0:400d8e75a8d0 10 // modification, are permitted provided that the following conditions
dflet 0:400d8e75a8d0 11 // are met:
dflet 0:400d8e75a8d0 12 //
dflet 0:400d8e75a8d0 13 // Redistributions of source code must retain the above copyright
dflet 0:400d8e75a8d0 14 // notice, this list of conditions and the following disclaimer.
dflet 0:400d8e75a8d0 15 //
dflet 0:400d8e75a8d0 16 // Redistributions in binary form must reproduce the above copyright
dflet 0:400d8e75a8d0 17 // notice, this list of conditions and the following disclaimer in the
dflet 0:400d8e75a8d0 18 // documentation and/or other materials provided with the
dflet 0:400d8e75a8d0 19 // distribution.
dflet 0:400d8e75a8d0 20 //
dflet 0:400d8e75a8d0 21 // Neither the name of Texas Instruments Incorporated nor the names of
dflet 0:400d8e75a8d0 22 // its contributors may be used to endorse or promote products derived
dflet 0:400d8e75a8d0 23 // from this software without specific prior written permission.
dflet 0:400d8e75a8d0 24 //
dflet 0:400d8e75a8d0 25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dflet 0:400d8e75a8d0 26 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dflet 0:400d8e75a8d0 27 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dflet 0:400d8e75a8d0 28 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
dflet 0:400d8e75a8d0 29 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
dflet 0:400d8e75a8d0 30 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
dflet 0:400d8e75a8d0 31 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
dflet 0:400d8e75a8d0 32 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
dflet 0:400d8e75a8d0 33 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
dflet 0:400d8e75a8d0 34 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
dflet 0:400d8e75a8d0 35 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dflet 0:400d8e75a8d0 36 //
dflet 0:400d8e75a8d0 37 //*****************************************************************************
dflet 0:400d8e75a8d0 38 //*****************************************************************************
dflet 0:400d8e75a8d0 39 //
dflet 0:400d8e75a8d0 40 //! \addtogroup camera_app
dflet 0:400d8e75a8d0 41 //! @{
dflet 0:400d8e75a8d0 42 //
dflet 0:400d8e75a8d0 43 //*****************************************************************************
dflet 0:400d8e75a8d0 44 #include "mbed.h"
dflet 0:400d8e75a8d0 45 #include <stdio.h>
dflet 0:400d8e75a8d0 46 #include <string.h>
dflet 0:400d8e75a8d0 47 #include <stdlib.h>
dflet 0:400d8e75a8d0 48
dflet 0:400d8e75a8d0 49 // SimpleLink include
dflet 0:400d8e75a8d0 50 #include "cc3100_simplelink.h"
dflet 0:400d8e75a8d0 51
dflet 0:400d8e75a8d0 52 #include "oslib/osi.h"
dflet 0:400d8e75a8d0 53 #include "camera_app.h"
dflet 0:400d8e75a8d0 54 #include "ArduCAM.h"
dflet 0:400d8e75a8d0 55 #include "ov5642_regs.h"
dflet 0:400d8e75a8d0 56 //#include "i2cconfig.h"
dflet 0:400d8e75a8d0 57 //#include "camera.h"
dflet 0:400d8e75a8d0 58
dflet 0:400d8e75a8d0 59 #include "app_config.h"
dflet 0:400d8e75a8d0 60 #include "cli_uart.h"
dflet 0:400d8e75a8d0 61 #include "Led_config.h"
dflet 0:400d8e75a8d0 62 #include "HttpDebug.h"
dflet 0:400d8e75a8d0 63
dflet 0:400d8e75a8d0 64 using namespace mbed_cc3100;
dflet 0:400d8e75a8d0 65
dflet 0:400d8e75a8d0 66
dflet 0:400d8e75a8d0 67 ArduCAM myCAM(OV5642, p14, SPI(p11, p12, p13), I2C(p28, p27));
dflet 0:400d8e75a8d0 68
dflet 0:400d8e75a8d0 69 //*****************************************************************************
dflet 0:400d8e75a8d0 70 // Macros
dflet 0:400d8e75a8d0 71 //*****************************************************************************
dflet 0:400d8e75a8d0 72 #define USER_FILE_NAME "www/images/cc3200_camera_capture.jpg"
dflet 0:400d8e75a8d0 73 #define TOTAL_DMA_ELEMENTS 64
dflet 0:400d8e75a8d0 74 #define AP_SSID_LEN_MAX (33)
dflet 0:400d8e75a8d0 75 #define ROLE_INVALID (-5)
dflet 0:400d8e75a8d0 76 //*****************************************************************************
dflet 0:400d8e75a8d0 77 // GLOBAL VARIABLES
dflet 0:400d8e75a8d0 78 //*****************************************************************************
dflet 0:400d8e75a8d0 79
dflet 0:400d8e75a8d0 80 unsigned int g_frame_size_in_bytes;
dflet 0:400d8e75a8d0 81 unsigned int g_uiDeviceModeConfig = ROLE_AP; //default is AP mode
dflet 0:400d8e75a8d0 82 extern volatile unsigned char g_CaptureImage;
dflet 0:400d8e75a8d0 83 extern int g_uiIpObtained = 0;
dflet 0:400d8e75a8d0 84 extern int g_uiSimplelinkRole = ROLE_INVALID;
dflet 0:400d8e75a8d0 85 uint32_t picLoop = 0;
dflet 0:400d8e75a8d0 86 unsigned int g_uiIpAddress = 0;
dflet 0:400d8e75a8d0 87 volatile static unsigned char g_frame_end;
dflet 0:400d8e75a8d0 88
dflet 0:400d8e75a8d0 89 #ifdef ENABLE_JPEG
dflet 0:400d8e75a8d0 90 int PIXELS_IN_X_AXIS = 320;
dflet 0:400d8e75a8d0 91 int PIXELS_IN_Y_AXIS = 240;
dflet 0:400d8e75a8d0 92 int FRAME_SIZE_IN_BYTES = (320 * 240 * 2);
dflet 0:400d8e75a8d0 93 #else
dflet 0:400d8e75a8d0 94 int PIXELS_IN_X_AXIS = 240;
dflet 0:400d8e75a8d0 95 int PIXELS_IN_Y_AXIS = 256;
dflet 0:400d8e75a8d0 96 int FRAME_SIZE_IN_BYTES = (240 * 256 * 2);
dflet 0:400d8e75a8d0 97 #endif
dflet 0:400d8e75a8d0 98
dflet 0:400d8e75a8d0 99 struct ImageBuffer
dflet 0:400d8e75a8d0 100 {
dflet 0:400d8e75a8d0 101 #ifdef ENABLE_JPEG
dflet 0:400d8e75a8d0 102 char g_header[SMTP_BUF_LEN] /*= {'\0'}*/;
dflet 0:400d8e75a8d0 103 #endif
dflet 0:400d8e75a8d0 104 uint8_t g_image_buffer[IMAGE_BUF_SIZE];//12Kb
dflet 0:400d8e75a8d0 105 };
dflet 0:400d8e75a8d0 106
dflet 0:400d8e75a8d0 107 ImageBuffer g_image;
dflet 0:400d8e75a8d0 108
dflet 0:400d8e75a8d0 109 typedef enum pictureRequest{
dflet 0:400d8e75a8d0 110 NO_PICTURE = 0x00,
dflet 0:400d8e75a8d0 111 SINGLE_HIGH_RESOLUTION = 0x01,
dflet 0:400d8e75a8d0 112 STREAM_LOW_RESOLUTION = 0x02
dflet 0:400d8e75a8d0 113
dflet 0:400d8e75a8d0 114 }e_pictureRequest;
dflet 0:400d8e75a8d0 115
dflet 0:400d8e75a8d0 116 typedef enum pictureFormat{
dflet 0:400d8e75a8d0 117 RAW_10BIT = 0,
dflet 0:400d8e75a8d0 118 ITU_R_BT601,
dflet 0:400d8e75a8d0 119 YCbCr_4_2_2,
dflet 0:400d8e75a8d0 120 YCbCr_4_2_0,
dflet 0:400d8e75a8d0 121 RGB_565,
dflet 0:400d8e75a8d0 122 RGB_555,
dflet 0:400d8e75a8d0 123 RGB_444
dflet 0:400d8e75a8d0 124
dflet 0:400d8e75a8d0 125 }e_pictureFormat;
dflet 0:400d8e75a8d0 126
dflet 0:400d8e75a8d0 127 typedef enum pictureResolution{
dflet 0:400d8e75a8d0 128 QVGA = 0,
dflet 0:400d8e75a8d0 129 VGA,
dflet 0:400d8e75a8d0 130 SVGA,
dflet 0:400d8e75a8d0 131 XGA,
dflet 0:400d8e75a8d0 132 uXGA
dflet 0:400d8e75a8d0 133
dflet 0:400d8e75a8d0 134 }e_pictureResolution;
dflet 0:400d8e75a8d0 135
dflet 0:400d8e75a8d0 136
dflet 0:400d8e75a8d0 137 #ifdef ENABLE_JPEG
dflet 0:400d8e75a8d0 138 #define FORMAT_YCBCR422 0
dflet 0:400d8e75a8d0 139 #define FORMAT_YCBCR420 1
dflet 0:400d8e75a8d0 140 #define FORMAT_MONOCHROME 2
dflet 0:400d8e75a8d0 141
dflet 0:400d8e75a8d0 142 unsigned char JPEG_StdQuantTblY[64] =
dflet 0:400d8e75a8d0 143 {
dflet 0:400d8e75a8d0 144 16, 11, 10, 16, 24, 40, 51, 61,
dflet 0:400d8e75a8d0 145 12, 12, 14, 19, 26, 58, 60, 55,
dflet 0:400d8e75a8d0 146 14, 13, 16, 24, 40, 57, 69, 56,
dflet 0:400d8e75a8d0 147 14, 17, 22, 29, 51, 87, 80, 62,
dflet 0:400d8e75a8d0 148 18, 22, 37, 56, 68, 109, 103, 77,
dflet 0:400d8e75a8d0 149 24, 35, 55, 64, 81, 104, 113, 92,
dflet 0:400d8e75a8d0 150 49, 64, 78, 87, 103, 121, 120, 101,
dflet 0:400d8e75a8d0 151 72, 92, 95, 98, 112, 100, 103, 99
dflet 0:400d8e75a8d0 152 };
dflet 0:400d8e75a8d0 153
dflet 0:400d8e75a8d0 154 unsigned char JPEG_StdQuantTblC[64] =
dflet 0:400d8e75a8d0 155 {
dflet 0:400d8e75a8d0 156 17, 18, 24, 47, 99, 99, 99, 99,
dflet 0:400d8e75a8d0 157 18, 21, 26, 66, 99, 99, 99, 99,
dflet 0:400d8e75a8d0 158 24, 26, 56, 99, 99, 99, 99, 99,
dflet 0:400d8e75a8d0 159 47, 66, 99, 99, 99, 99, 99, 99,
dflet 0:400d8e75a8d0 160 99, 99, 99, 99, 99, 99, 99, 99,
dflet 0:400d8e75a8d0 161 99, 99, 99, 99, 99, 99, 99, 99,
dflet 0:400d8e75a8d0 162 99, 99, 99, 99, 99, 99, 99, 99,
dflet 0:400d8e75a8d0 163 99, 99, 99, 99, 99, 99, 99, 99
dflet 0:400d8e75a8d0 164 };
dflet 0:400d8e75a8d0 165 //
dflet 0:400d8e75a8d0 166 // This table is used for regular-position to zigzagged-position lookup
dflet 0:400d8e75a8d0 167 // This is Figure A.6 from the ISO/IEC 10918-1 1993 specification
dflet 0:400d8e75a8d0 168 //
dflet 0:400d8e75a8d0 169 static unsigned char zigzag[64] =
dflet 0:400d8e75a8d0 170 {
dflet 0:400d8e75a8d0 171 0, 1, 5, 6,14,15,27,28,
dflet 0:400d8e75a8d0 172 2, 4, 7,13,16,26,29,42,
dflet 0:400d8e75a8d0 173 3, 8,12,17,25,30,41,43,
dflet 0:400d8e75a8d0 174 9,11,18,24,31,40,44,53,
dflet 0:400d8e75a8d0 175 10,19,23,32,39,45,52,54,
dflet 0:400d8e75a8d0 176 20,22,33,38,46,51,55,60,
dflet 0:400d8e75a8d0 177 21,34,37,47,50,56,59,61,
dflet 0:400d8e75a8d0 178 35,36,48,49,57,58,62,63
dflet 0:400d8e75a8d0 179 };
dflet 0:400d8e75a8d0 180
dflet 0:400d8e75a8d0 181 unsigned int JPEG_StdHuffmanTbl[384] =
dflet 0:400d8e75a8d0 182 {
dflet 0:400d8e75a8d0 183 0x100, 0x101, 0x204, 0x30b, 0x41a, 0x678, 0x7f8, 0x9f6,
dflet 0:400d8e75a8d0 184 0xf82, 0xf83, 0x30c, 0x41b, 0x679, 0x8f6, 0xaf6, 0xf84,
dflet 0:400d8e75a8d0 185 0xf85, 0xf86, 0xf87, 0xf88, 0x41c, 0x7f9, 0x9f7, 0xbf4,
dflet 0:400d8e75a8d0 186 0xf89, 0xf8a, 0xf8b, 0xf8c, 0xf8d, 0xf8e, 0x53a, 0x8f7,
dflet 0:400d8e75a8d0 187 0xbf5, 0xf8f, 0xf90, 0xf91, 0xf92, 0xf93, 0xf94, 0xf95,
dflet 0:400d8e75a8d0 188 0x53b, 0x9f8, 0xf96, 0xf97, 0xf98, 0xf99, 0xf9a, 0xf9b,
dflet 0:400d8e75a8d0 189 0xf9c, 0xf9d, 0x67a, 0xaf7, 0xf9e, 0xf9f, 0xfa0, 0xfa1,
dflet 0:400d8e75a8d0 190 0xfa2, 0xfa3, 0xfa4, 0xfa5, 0x67b, 0xbf6, 0xfa6, 0xfa7,
dflet 0:400d8e75a8d0 191 0xfa8, 0xfa9, 0xfaa, 0xfab, 0xfac, 0xfad, 0x7fa, 0xbf7,
dflet 0:400d8e75a8d0 192 0xfae, 0xfaf, 0xfb0, 0xfb1, 0xfb2, 0xfb3, 0xfb4, 0xfb5,
dflet 0:400d8e75a8d0 193 0x8f8, 0xec0, 0xfb6, 0xfb7, 0xfb8, 0xfb9, 0xfba, 0xfbb,
dflet 0:400d8e75a8d0 194 0xfbc, 0xfbd, 0x8f9, 0xfbe, 0xfbf, 0xfc0, 0xfc1, 0xfc2,
dflet 0:400d8e75a8d0 195 0xfc3, 0xfc4, 0xfc5, 0xfc6, 0x8fa, 0xfc7, 0xfc8, 0xfc9,
dflet 0:400d8e75a8d0 196 0xfca, 0xfcb, 0xfcc, 0xfcd, 0xfce, 0xfcf, 0x9f9, 0xfd0,
dflet 0:400d8e75a8d0 197 0xfd1, 0xfd2, 0xfd3, 0xfd4, 0xfd5, 0xfd6, 0xfd7, 0xfd8,
dflet 0:400d8e75a8d0 198 0x9fa, 0xfd9, 0xfda, 0xfdb, 0xfdc, 0xfdd, 0xfde, 0xfdf,
dflet 0:400d8e75a8d0 199 0xfe0, 0xfe1, 0xaf8, 0xfe2, 0xfe3, 0xfe4, 0xfe5, 0xfe6,
dflet 0:400d8e75a8d0 200 0xfe7, 0xfe8, 0xfe9, 0xfea, 0xfeb, 0xfec, 0xfed, 0xfee,
dflet 0:400d8e75a8d0 201 0xfef, 0xff0, 0xff1, 0xff2, 0xff3, 0xff4, 0xff5, 0xff6,
dflet 0:400d8e75a8d0 202 0xff7, 0xff8, 0xff9, 0xffa, 0xffb, 0xffc, 0xffd, 0xffe,
dflet 0:400d8e75a8d0 203 0x30a, 0xaf9, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
dflet 0:400d8e75a8d0 204 0xfd0, 0xfd1, 0xfd2, 0xfd3, 0xfd4, 0xfd5, 0xfd6, 0xfd7,
dflet 0:400d8e75a8d0 205 0x101, 0x204, 0x30a, 0x418, 0x419, 0x538, 0x678, 0x8f4,
dflet 0:400d8e75a8d0 206 0x9f6, 0xbf4, 0x30b, 0x539, 0x7f6, 0x8f5, 0xaf6, 0xbf5,
dflet 0:400d8e75a8d0 207 0xf88, 0xf89, 0xf8a, 0xf8b, 0x41a, 0x7f7, 0x9f7, 0xbf6,
dflet 0:400d8e75a8d0 208 0xec2, 0xf8c, 0xf8d, 0xf8e, 0xf8f, 0xf90, 0x41b, 0x7f8,
dflet 0:400d8e75a8d0 209 0x9f8, 0xbf7, 0xf91, 0xf92, 0xf93, 0xf94, 0xf95, 0xf96,
dflet 0:400d8e75a8d0 210 0x53a, 0x8f6, 0xf97, 0xf98, 0xf99, 0xf9a, 0xf9b, 0xf9c,
dflet 0:400d8e75a8d0 211 0xf9d, 0xf9e, 0x53b, 0x9f9, 0xf9f, 0xfa0, 0xfa1, 0xfa2,
dflet 0:400d8e75a8d0 212 0xfa3, 0xfa4, 0xfa5, 0xfa6, 0x679, 0xaf7, 0xfa7, 0xfa8,
dflet 0:400d8e75a8d0 213 0xfa9, 0xfaa, 0xfab, 0xfac, 0xfad, 0xfae, 0x67a, 0xaf8,
dflet 0:400d8e75a8d0 214 0xfaf, 0xfb0, 0xfb1, 0xfb2, 0xfb3, 0xfb4, 0xfb5, 0xfb6,
dflet 0:400d8e75a8d0 215 0x7f9, 0xfb7, 0xfb8, 0xfb9, 0xfba, 0xfbb, 0xfbc, 0xfbd,
dflet 0:400d8e75a8d0 216 0xfbe, 0xfbf, 0x8f7, 0xfc0, 0xfc1, 0xfc2, 0xfc3, 0xfc4,
dflet 0:400d8e75a8d0 217 0xfc5, 0xfc6, 0xfc7, 0xfc8, 0x8f8, 0xfc9, 0xfca, 0xfcb,
dflet 0:400d8e75a8d0 218 0xfcc, 0xfcd, 0xfce, 0xfcf, 0xfd0, 0xfd1, 0x8f9, 0xfd2,
dflet 0:400d8e75a8d0 219 0xfd3, 0xfd4, 0xfd5, 0xfd6, 0xfd7, 0xfd8, 0xfd9, 0xfda,
dflet 0:400d8e75a8d0 220 0x8fa, 0xfdb, 0xfdc, 0xfdd, 0xfde, 0xfdf, 0xfe0, 0xfe1,
dflet 0:400d8e75a8d0 221 0xfe2, 0xfe3, 0xaf9, 0xfe4, 0xfe5, 0xfe6, 0xfe7, 0xfe8,
dflet 0:400d8e75a8d0 222 0xfe9, 0xfea, 0xfeb, 0xfec, 0xde0, 0xfed, 0xfee, 0xfef,
dflet 0:400d8e75a8d0 223 0xff0, 0xff1, 0xff2, 0xff3, 0xff4, 0xff5, 0xec3, 0xff6,
dflet 0:400d8e75a8d0 224 0xff7, 0xff8, 0xff9, 0xffa, 0xffb, 0xffc, 0xffd, 0xffe,
dflet 0:400d8e75a8d0 225 0x100, 0x9fa, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
dflet 0:400d8e75a8d0 226 0xfd0, 0xfd1, 0xfd2, 0xfd3, 0xfd4, 0xfd5, 0xfd6, 0xfd7,
dflet 0:400d8e75a8d0 227 0x100, 0x202, 0x203, 0x204, 0x205, 0x206, 0x30e, 0x41e,
dflet 0:400d8e75a8d0 228 0x53e, 0x67e, 0x7fe, 0x8fe, 0xfff, 0xfff, 0xfff, 0xfff,
dflet 0:400d8e75a8d0 229 0x100, 0x101, 0x102, 0x206, 0x30e, 0x41e, 0x53e, 0x67e,
dflet 0:400d8e75a8d0 230 0x7fe, 0x8fe, 0x9fe, 0xafe, 0xfff, 0xfff, 0xfff, 0xfff
dflet 0:400d8e75a8d0 231 };
dflet 0:400d8e75a8d0 232 #endif
dflet 0:400d8e75a8d0 233
dflet 0:400d8e75a8d0 234 //*****************************************************************************
dflet 0:400d8e75a8d0 235 //
dflet 0:400d8e75a8d0 236 //! Start Camera
dflet 0:400d8e75a8d0 237 //! 1. Establishes connection w/ AP//
dflet 0:400d8e75a8d0 238 //! 2. Initializes the camera sub-components//! GPIO Enable & Configuration
dflet 0:400d8e75a8d0 239 //! 3. Listens and processes the image capture requests from user-applications
dflet 0:400d8e75a8d0 240 //!
dflet 0:400d8e75a8d0 241 //! \param[out] WriteBuffer - Pointer to the Frame Buffer
dflet 0:400d8e75a8d0 242 //! \return None
dflet 0:400d8e75a8d0 243 //
dflet 0:400d8e75a8d0 244 //*****************************************************************************
dflet 0:400d8e75a8d0 245
dflet 0:400d8e75a8d0 246 unsigned short StartCamera(char **WriteBuffer)
dflet 0:400d8e75a8d0 247 {
dflet 0:400d8e75a8d0 248 unsigned short Writelength;
dflet 0:400d8e75a8d0 249 //
dflet 0:400d8e75a8d0 250 // Waits in the below loop till Capture button is pressed
dflet 0:400d8e75a8d0 251 //
dflet 0:400d8e75a8d0 252 Writelength = CaptureImage(WriteBuffer);
dflet 0:400d8e75a8d0 253
dflet 0:400d8e75a8d0 254 return(Writelength);
dflet 0:400d8e75a8d0 255
dflet 0:400d8e75a8d0 256 }
dflet 0:400d8e75a8d0 257 //*****************************************************************************
dflet 0:400d8e75a8d0 258 //
dflet 0:400d8e75a8d0 259 //! InitCameraComponents
dflet 0:400d8e75a8d0 260 //! PinMux, Camera Initialization and Configuration
dflet 0:400d8e75a8d0 261 //!
dflet 0:400d8e75a8d0 262 //! \param[in] width - X-Axis
dflet 0:400d8e75a8d0 263 //! \param[in] width - Y-Axis
dflet 0:400d8e75a8d0 264 //! \return None
dflet 0:400d8e75a8d0 265 //
dflet 0:400d8e75a8d0 266 //*****************************************************************************
dflet 0:400d8e75a8d0 267
dflet 0:400d8e75a8d0 268 void InitCameraComponents(int width, int height)
dflet 0:400d8e75a8d0 269 {
dflet 0:400d8e75a8d0 270 getCamId();
dflet 0:400d8e75a8d0 271
dflet 0:400d8e75a8d0 272 #ifdef ENABLE_JPEG
dflet 0:400d8e75a8d0 273 //Change to JPEG capture mode and initialize the OV5642 module
dflet 0:400d8e75a8d0 274 myCAM.set_format(JPEG);
dflet 0:400d8e75a8d0 275 #endif
dflet 0:400d8e75a8d0 276
dflet 0:400d8e75a8d0 277 //
dflet 0:400d8e75a8d0 278 // Initialize camera sensor
dflet 0:400d8e75a8d0 279 //
dflet 0:400d8e75a8d0 280 myCAM.InitCAM();
dflet 0:400d8e75a8d0 281 myCAM.clear_fifo_flag();
dflet 0:400d8e75a8d0 282 myCAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
dflet 0:400d8e75a8d0 283 myCAM.write_reg(ARDUCHIP_FRAMES,0x00); //Bit[2:0]Number of frames to be captured
dflet 0:400d8e75a8d0 284
dflet 0:400d8e75a8d0 285 }
dflet 0:400d8e75a8d0 286
dflet 0:400d8e75a8d0 287 void getCamId(){
dflet 0:400d8e75a8d0 288
dflet 0:400d8e75a8d0 289 uint8_t vid = 0;
dflet 0:400d8e75a8d0 290 uint8_t pid = 0;
dflet 0:400d8e75a8d0 291
dflet 0:400d8e75a8d0 292 //Check if the camera module type is OV5642
dflet 0:400d8e75a8d0 293 myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
dflet 0:400d8e75a8d0 294 myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);
dflet 0:400d8e75a8d0 295 if((vid != 0x56) || (pid != 0x42)){
dflet 0:400d8e75a8d0 296 printf("Can't find OV5642 module! vid = 0x%x pid = 0x%x\r\n",vid, pid);
dflet 0:400d8e75a8d0 297 while(1);
dflet 0:400d8e75a8d0 298 }else{
dflet 0:400d8e75a8d0 299 printf("OV5642 detected\r\n");
dflet 0:400d8e75a8d0 300 }
dflet 0:400d8e75a8d0 301 }
dflet 0:400d8e75a8d0 302
dflet 0:400d8e75a8d0 303 //*****************************************************************************
dflet 0:400d8e75a8d0 304 //
dflet 0:400d8e75a8d0 305 //! CaptureImage
dflet 0:400d8e75a8d0 306 //! Configures DMA and starts the Capture. Post Capture writes to SFLASH
dflet 0:400d8e75a8d0 307 //!
dflet 0:400d8e75a8d0 308 //! \param None
dflet 0:400d8e75a8d0 309 //! \return None
dflet 0:400d8e75a8d0 310 //!
dflet 0:400d8e75a8d0 311 //
dflet 0:400d8e75a8d0 312 //*****************************************************************************
dflet 0:400d8e75a8d0 313 uint16_t CaptureImage(char** WriteBuffer)
dflet 0:400d8e75a8d0 314 {
dflet 0:400d8e75a8d0 315
dflet 0:400d8e75a8d0 316 //uint32_t g_header_length = 0;
dflet 0:400d8e75a8d0 317 myCAM.flush_fifo();
dflet 0:400d8e75a8d0 318 wait_ms(5);
dflet 0:400d8e75a8d0 319 myCAM.clear_fifo_flag();
dflet 0:400d8e75a8d0 320 wait(1);
dflet 0:400d8e75a8d0 321 //
dflet 0:400d8e75a8d0 322 // Perform Image Capture
dflet 0:400d8e75a8d0 323 //
dflet 0:400d8e75a8d0 324 #ifdef ENABLE_JPEG
dflet 0:400d8e75a8d0 325 myCAM.start_capture();
dflet 0:400d8e75a8d0 326 #else
dflet 0:400d8e75a8d0 327
dflet 0:400d8e75a8d0 328 #endif
dflet 0:400d8e75a8d0 329
dflet 0:400d8e75a8d0 330 while (!(myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK))){
dflet 0:400d8e75a8d0 331 wait_ms(100);
dflet 0:400d8e75a8d0 332 }
dflet 0:400d8e75a8d0 333 g_frame_size_in_bytes = myCAM.read_fifo_length();
dflet 0:400d8e75a8d0 334 read_fifo_burst();
dflet 0:400d8e75a8d0 335
dflet 0:400d8e75a8d0 336 /* Read the number of data items transferred in bytes) */
dflet 0:400d8e75a8d0 337 if(g_frame_size_in_bytes <= 0 ){
dflet 0:400d8e75a8d0 338 HttpDebug("\r\nFailed to capture or data over-run, check camera connections!\r\n");
dflet 0:400d8e75a8d0 339 while(1){
dflet 0:400d8e75a8d0 340 wait(0.5);
dflet 0:400d8e75a8d0 341 }
dflet 0:400d8e75a8d0 342 }
dflet 0:400d8e75a8d0 343
dflet 0:400d8e75a8d0 344 //
dflet 0:400d8e75a8d0 345 // Create JPEG Header
dflet 0:400d8e75a8d0 346 //
dflet 0:400d8e75a8d0 347 #ifdef ENABLE_JPEG
dflet 0:400d8e75a8d0 348 // memset(g_image.g_header, '\0', sizeof(g_image.g_header));
dflet 0:400d8e75a8d0 349 // g_header_length = CreateJpegHeader((char *)&(g_image.g_header[0]), PIXELS_IN_X_AXIS,
dflet 0:400d8e75a8d0 350 // PIXELS_IN_Y_AXIS, 0, 0x0020, 9);
dflet 0:400d8e75a8d0 351 // HttpDebug("g_header_length = 0x%x \r\n",g_header_length);
dflet 0:400d8e75a8d0 352 // This pushes the header to the start of the array so that the entire picture can be contiguous in memory
dflet 0:400d8e75a8d0 353 // memcpy(Image + g_header_length, Image, g_frame_size_in_bytes);
dflet 0:400d8e75a8d0 354 // memcpy(Image, g_image.g_header, g_header_length);
dflet 0:400d8e75a8d0 355 // This pushes the header to the end of the array so that the entire picture can be contiguous in memory
dflet 0:400d8e75a8d0 356 // memcpy(Image + g_frame_size_in_bytes, g_image.g_header, g_header_length);
dflet 0:400d8e75a8d0 357
dflet 0:400d8e75a8d0 358 #endif//ENABLE_JPEG
dflet 0:400d8e75a8d0 359 picLoop++;
dflet 0:400d8e75a8d0 360 HttpDebug("\r\nPicture Sent %d\r\n",picLoop);
dflet 0:400d8e75a8d0 361
dflet 0:400d8e75a8d0 362 *WriteBuffer = (char*)g_image.g_image_buffer;
dflet 0:400d8e75a8d0 363
dflet 0:400d8e75a8d0 364 return(g_frame_size_in_bytes);
dflet 0:400d8e75a8d0 365 }
dflet 0:400d8e75a8d0 366
dflet 0:400d8e75a8d0 367 uint8_t read_fifo_burst()
dflet 0:400d8e75a8d0 368 {
dflet 0:400d8e75a8d0 369
dflet 0:400d8e75a8d0 370 uint32_t bytesRead = 0;
dflet 0:400d8e75a8d0 371 uint8_t temp = 0;
dflet 0:400d8e75a8d0 372 uint8_t temp_last = 0;
dflet 0:400d8e75a8d0 373 int32_t i;
dflet 0:400d8e75a8d0 374
dflet 0:400d8e75a8d0 375 myCAM.cs_low();
dflet 0:400d8e75a8d0 376 myCAM.set_fifo_burst();
dflet 0:400d8e75a8d0 377 myCAM._cam_spi.write(0x00);//Ignore first byte
dflet 0:400d8e75a8d0 378 i = 0;
dflet 0:400d8e75a8d0 379 while( 1 ){
dflet 0:400d8e75a8d0 380 temp_last = temp;
dflet 0:400d8e75a8d0 381 temp = (uint8_t )myCAM._cam_spi.write(0x00);
dflet 0:400d8e75a8d0 382 g_image.g_image_buffer[i] = temp;
dflet 0:400d8e75a8d0 383 i++;
dflet 0:400d8e75a8d0 384 bytesRead++;
dflet 0:400d8e75a8d0 385 if( temp == 0xD9 && temp_last == 0xFF ){
dflet 0:400d8e75a8d0 386 break;
dflet 0:400d8e75a8d0 387 }
dflet 0:400d8e75a8d0 388 if(i>= 1024 *10){
dflet 0:400d8e75a8d0 389 HttpDebug("\r\nFile size exceeds 10K limit 0x%x\r\n",bytesRead);
dflet 0:400d8e75a8d0 390 break;
dflet 0:400d8e75a8d0 391 }
dflet 0:400d8e75a8d0 392 }
dflet 0:400d8e75a8d0 393 g_frame_size_in_bytes = bytesRead;
dflet 0:400d8e75a8d0 394 myCAM.cs_high();
dflet 0:400d8e75a8d0 395
dflet 0:400d8e75a8d0 396 return 1;
dflet 0:400d8e75a8d0 397 }
dflet 0:400d8e75a8d0 398
dflet 0:400d8e75a8d0 399 //*****************************************************************************
dflet 0:400d8e75a8d0 400 //
dflet 0:400d8e75a8d0 401 //! JfifApp0Marker
dflet 0:400d8e75a8d0 402 //!
dflet 0:400d8e75a8d0 403 //! \param Pointer to the output buffer
dflet 0:400d8e75a8d0 404 //! \return Length of the Marker
dflet 0:400d8e75a8d0 405 //
dflet 0:400d8e75a8d0 406 //*****************************************************************************
dflet 0:400d8e75a8d0 407
dflet 0:400d8e75a8d0 408 #ifdef ENABLE_JPEG
dflet 0:400d8e75a8d0 409 static int JfifApp0Marker(char *pbuf)
dflet 0:400d8e75a8d0 410 {
dflet 0:400d8e75a8d0 411 *pbuf++= 0xFF; // APP0 marker
dflet 0:400d8e75a8d0 412 *pbuf++= 0xE0;
dflet 0:400d8e75a8d0 413 *pbuf++= 0x00; // length
dflet 0:400d8e75a8d0 414 *pbuf++= 0x10;
dflet 0:400d8e75a8d0 415 *pbuf++= 0x4A; // JFIF identifier
dflet 0:400d8e75a8d0 416 *pbuf++= 0x46;
dflet 0:400d8e75a8d0 417 *pbuf++= 0x49;
dflet 0:400d8e75a8d0 418 *pbuf++= 0x46;
dflet 0:400d8e75a8d0 419 *pbuf++= 0x00;
dflet 0:400d8e75a8d0 420 *pbuf++= 0x01; // version
dflet 0:400d8e75a8d0 421 *pbuf++= 0x02;
dflet 0:400d8e75a8d0 422 *pbuf++= 0x00; // units
dflet 0:400d8e75a8d0 423 *pbuf++= 0x00; // X density
dflet 0:400d8e75a8d0 424 *pbuf++= 0x01;
dflet 0:400d8e75a8d0 425 *pbuf++= 0x00; // Y density
dflet 0:400d8e75a8d0 426 *pbuf++= 0x01;
dflet 0:400d8e75a8d0 427 *pbuf++= 0x00; // X thumbnail
dflet 0:400d8e75a8d0 428 *pbuf++= 0x00; // Y thumbnail
dflet 0:400d8e75a8d0 429 return 18;
dflet 0:400d8e75a8d0 430 }
dflet 0:400d8e75a8d0 431
dflet 0:400d8e75a8d0 432
dflet 0:400d8e75a8d0 433 //*****************************************************************************
dflet 0:400d8e75a8d0 434 //
dflet 0:400d8e75a8d0 435 //! FrameHeaderMarker
dflet 0:400d8e75a8d0 436 //!
dflet 0:400d8e75a8d0 437 //! \param1 pointer to the output buffer
dflet 0:400d8e75a8d0 438 //! \param2 width
dflet 0:400d8e75a8d0 439 //! \param3 height
dflet 0:400d8e75a8d0 440 //! \param4 format
dflet 0:400d8e75a8d0 441 //!
dflet 0:400d8e75a8d0 442 //! \return Length of the header marker
dflet 0:400d8e75a8d0 443 //
dflet 0:400d8e75a8d0 444 //*****************************************************************************
dflet 0:400d8e75a8d0 445 static int FrameHeaderMarker(char *pbuf, int width, int height, int format)
dflet 0:400d8e75a8d0 446 {
dflet 0:400d8e75a8d0 447 int length;
dflet 0:400d8e75a8d0 448 if (format == FORMAT_MONOCHROME)
dflet 0:400d8e75a8d0 449 length = 11;
dflet 0:400d8e75a8d0 450 else
dflet 0:400d8e75a8d0 451 length = 17;
dflet 0:400d8e75a8d0 452
dflet 0:400d8e75a8d0 453 *pbuf++= 0xFF; // start of frame: baseline DCT
dflet 0:400d8e75a8d0 454 *pbuf++= 0xC0;
dflet 0:400d8e75a8d0 455 *pbuf++= length>>8; // length field
dflet 0:400d8e75a8d0 456 *pbuf++= length&0xFF;
dflet 0:400d8e75a8d0 457 *pbuf++= 0x08; // sample precision
dflet 0:400d8e75a8d0 458 *pbuf++= height>>8; // number of lines
dflet 0:400d8e75a8d0 459 *pbuf++= height&0xFF;
dflet 0:400d8e75a8d0 460 *pbuf++= width>>8; // number of samples per line
dflet 0:400d8e75a8d0 461 *pbuf++= width&0xFF;
dflet 0:400d8e75a8d0 462
dflet 0:400d8e75a8d0 463 if (format == FORMAT_MONOCHROME) // monochrome
dflet 0:400d8e75a8d0 464 {
dflet 0:400d8e75a8d0 465 *pbuf++= 0x01; // number of image components in frame
dflet 0:400d8e75a8d0 466 *pbuf++= 0x00; // component identifier: Y
dflet 0:400d8e75a8d0 467 *pbuf++= 0x11; // horizontal | vertical sampling factor: Y
dflet 0:400d8e75a8d0 468 *pbuf++= 0x00; // quantization table selector: Y
dflet 0:400d8e75a8d0 469 }
dflet 0:400d8e75a8d0 470 else if (format == FORMAT_YCBCR422) // YCbCr422
dflet 0:400d8e75a8d0 471 {
dflet 0:400d8e75a8d0 472 *pbuf++= 0x03; // number of image components in frame
dflet 0:400d8e75a8d0 473 *pbuf++= 0x00; // component identifier: Y
dflet 0:400d8e75a8d0 474 *pbuf++= 0x21; // horizontal | vertical sampling factor: Y
dflet 0:400d8e75a8d0 475 *pbuf++= 0x00; // quantization table selector: Y
dflet 0:400d8e75a8d0 476 *pbuf++= 0x01; // component identifier: Cb
dflet 0:400d8e75a8d0 477 *pbuf++= 0x11; // horizontal | vertical sampling factor: Cb
dflet 0:400d8e75a8d0 478 *pbuf++= 0x01; // quantization table selector: Cb
dflet 0:400d8e75a8d0 479 *pbuf++= 0x02; // component identifier: Cr
dflet 0:400d8e75a8d0 480 *pbuf++= 0x11; // horizontal | vertical sampling factor: Cr
dflet 0:400d8e75a8d0 481 *pbuf++= 0x01; // quantization table selector: Cr
dflet 0:400d8e75a8d0 482 }
dflet 0:400d8e75a8d0 483 else // YCbCr420
dflet 0:400d8e75a8d0 484 {
dflet 0:400d8e75a8d0 485 *pbuf++= 0x03; // number of image components in frame
dflet 0:400d8e75a8d0 486 *pbuf++= 0x00; // component identifier: Y
dflet 0:400d8e75a8d0 487 *pbuf++= 0x22; // horizontal | vertical sampling factor: Y
dflet 0:400d8e75a8d0 488 *pbuf++= 0x00; // quantization table selector: Y
dflet 0:400d8e75a8d0 489 *pbuf++= 0x01; // component identifier: Cb
dflet 0:400d8e75a8d0 490 *pbuf++= 0x11; // horizontal | vertical sampling factor: Cb
dflet 0:400d8e75a8d0 491 *pbuf++= 0x01; // quantization table selector: Cb
dflet 0:400d8e75a8d0 492 *pbuf++= 0x02; // component identifier: Cr
dflet 0:400d8e75a8d0 493 *pbuf++= 0x11; // horizontal | vertical sampling factor: Cr
dflet 0:400d8e75a8d0 494 *pbuf++= 0x01; // quantization table selector: Cr
dflet 0:400d8e75a8d0 495 }
dflet 0:400d8e75a8d0 496
dflet 0:400d8e75a8d0 497 return (length+2);
dflet 0:400d8e75a8d0 498 }
dflet 0:400d8e75a8d0 499
dflet 0:400d8e75a8d0 500
dflet 0:400d8e75a8d0 501 //*****************************************************************************
dflet 0:400d8e75a8d0 502 //
dflet 0:400d8e75a8d0 503 //! ScanHeaderMarker
dflet 0:400d8e75a8d0 504 //!
dflet 0:400d8e75a8d0 505 //! \param1 pointer to output buffer
dflet 0:400d8e75a8d0 506 //! \param2 Format
dflet 0:400d8e75a8d0 507 //!
dflet 0:400d8e75a8d0 508 //! \return Length
dflet 0:400d8e75a8d0 509 //
dflet 0:400d8e75a8d0 510 //*****************************************************************************
dflet 0:400d8e75a8d0 511 static int ScanHeaderMarker(char *pbuf, int format)
dflet 0:400d8e75a8d0 512 {
dflet 0:400d8e75a8d0 513 int length;
dflet 0:400d8e75a8d0 514 if (format == FORMAT_MONOCHROME)
dflet 0:400d8e75a8d0 515 length = 8;
dflet 0:400d8e75a8d0 516 else
dflet 0:400d8e75a8d0 517 length = 12;
dflet 0:400d8e75a8d0 518
dflet 0:400d8e75a8d0 519 *pbuf++= 0xFF; // start of scan
dflet 0:400d8e75a8d0 520 *pbuf++= 0xDA;
dflet 0:400d8e75a8d0 521 *pbuf++= length>>8; // length field
dflet 0:400d8e75a8d0 522 *pbuf++= length&0xFF;
dflet 0:400d8e75a8d0 523 if (format == FORMAT_MONOCHROME)// monochrome
dflet 0:400d8e75a8d0 524 {
dflet 0:400d8e75a8d0 525 *pbuf++= 0x01; // number of image components in scan
dflet 0:400d8e75a8d0 526 *pbuf++= 0x00; // scan component selector: Y
dflet 0:400d8e75a8d0 527 *pbuf++= 0x00; // DC | AC huffman table selector: Y
dflet 0:400d8e75a8d0 528 }
dflet 0:400d8e75a8d0 529 else // YCbCr
dflet 0:400d8e75a8d0 530 {
dflet 0:400d8e75a8d0 531 *pbuf++= 0x03; // number of image components in scan
dflet 0:400d8e75a8d0 532 *pbuf++= 0x00; // scan component selector: Y
dflet 0:400d8e75a8d0 533 *pbuf++= 0x00; // DC | AC huffman table selector: Y
dflet 0:400d8e75a8d0 534 *pbuf++= 0x01; // scan component selector: Cb
dflet 0:400d8e75a8d0 535 *pbuf++= 0x11; // DC | AC huffman table selector: Cb
dflet 0:400d8e75a8d0 536 *pbuf++= 0x02; // scan component selector: Cr
dflet 0:400d8e75a8d0 537 *pbuf++= 0x11; // DC | AC huffman table selector: Cr
dflet 0:400d8e75a8d0 538 }
dflet 0:400d8e75a8d0 539
dflet 0:400d8e75a8d0 540 *pbuf++= 0x00; // Ss: start of predictor selector
dflet 0:400d8e75a8d0 541 *pbuf++= 0x3F; // Se: end of spectral selector
dflet 0:400d8e75a8d0 542 *pbuf++= 0x00; // Ah | Al: successive approximation bit position
dflet 0:400d8e75a8d0 543
dflet 0:400d8e75a8d0 544 return (length+2);
dflet 0:400d8e75a8d0 545 }
dflet 0:400d8e75a8d0 546
dflet 0:400d8e75a8d0 547
dflet 0:400d8e75a8d0 548 //*****************************************************************************
dflet 0:400d8e75a8d0 549 //
dflet 0:400d8e75a8d0 550 //! DefineQuantizationTableMarker
dflet 0:400d8e75a8d0 551 //! Calculate and write the quantisation tables
dflet 0:400d8e75a8d0 552 //! qscale is the customised scaling factor - see MT9D131 developer guide page 78
dflet 0:400d8e75a8d0 553 //!
dflet 0:400d8e75a8d0 554 //! \param1 pointer to the output buffer
dflet 0:400d8e75a8d0 555 //! \param2 Quantization Scale
dflet 0:400d8e75a8d0 556 //! \param3 Format
dflet 0:400d8e75a8d0 557 //!
dflet 0:400d8e75a8d0 558 //! \return Length of the Marker
dflet 0:400d8e75a8d0 559 //
dflet 0:400d8e75a8d0 560 //*****************************************************************************
dflet 0:400d8e75a8d0 561 static int DefineQuantizationTableMarker (unsigned char *pbuf, int qscale, int format)
dflet 0:400d8e75a8d0 562 {
dflet 0:400d8e75a8d0 563 int i, length, temp;
dflet 0:400d8e75a8d0 564 unsigned char newtbl[64]; // temporary array to store scaled zigzagged quant entries
dflet 0:400d8e75a8d0 565
dflet 0:400d8e75a8d0 566 if (format == FORMAT_MONOCHROME) // monochrome
dflet 0:400d8e75a8d0 567 length = 67;
dflet 0:400d8e75a8d0 568 else
dflet 0:400d8e75a8d0 569 length = 132;
dflet 0:400d8e75a8d0 570
dflet 0:400d8e75a8d0 571 *pbuf++ = 0xFF; // define quantization table marker
dflet 0:400d8e75a8d0 572 *pbuf++ = 0xDB;
dflet 0:400d8e75a8d0 573 *pbuf++ = length>>8; // length field
dflet 0:400d8e75a8d0 574 *pbuf++ = length&0xFF;
dflet 0:400d8e75a8d0 575 *pbuf++ = 0; // quantization table precision | identifier for luminance
dflet 0:400d8e75a8d0 576
dflet 0:400d8e75a8d0 577 // calculate scaled zigzagged luminance quantisation table entries
dflet 0:400d8e75a8d0 578 for (i=0; i<64; i++) {
dflet 0:400d8e75a8d0 579 temp = (JPEG_StdQuantTblY[i] * qscale + 16) / 32;
dflet 0:400d8e75a8d0 580 // limit the values to the valid range
dflet 0:400d8e75a8d0 581 if (temp <= 0)
dflet 0:400d8e75a8d0 582 temp = 1;
dflet 0:400d8e75a8d0 583 if (temp > 255)
dflet 0:400d8e75a8d0 584 temp = 255;
dflet 0:400d8e75a8d0 585 newtbl[zigzag[i]] = (unsigned char) temp;
dflet 0:400d8e75a8d0 586 }
dflet 0:400d8e75a8d0 587
dflet 0:400d8e75a8d0 588 // write the resulting luminance quant table to the output buffer
dflet 0:400d8e75a8d0 589 for (i=0; i<64; i++)
dflet 0:400d8e75a8d0 590 *pbuf++ = newtbl[i];
dflet 0:400d8e75a8d0 591
dflet 0:400d8e75a8d0 592 // if format is monochrome we're finished, otherwise continue on, to do chrominance quant table
dflet 0:400d8e75a8d0 593 if (format == FORMAT_MONOCHROME)
dflet 0:400d8e75a8d0 594 return (length+2);
dflet 0:400d8e75a8d0 595
dflet 0:400d8e75a8d0 596 *pbuf++ = 1; // quantization table precision | identifier for chrominance
dflet 0:400d8e75a8d0 597
dflet 0:400d8e75a8d0 598 // calculate scaled zigzagged chrominance quantisation table entries
dflet 0:400d8e75a8d0 599 for (i=0; i<64; i++) {
dflet 0:400d8e75a8d0 600 temp = (JPEG_StdQuantTblC[i] * qscale + 16) / 32;
dflet 0:400d8e75a8d0 601 // limit the values to the valid range
dflet 0:400d8e75a8d0 602 if (temp <= 0)
dflet 0:400d8e75a8d0 603 temp = 1;
dflet 0:400d8e75a8d0 604 if (temp > 255)
dflet 0:400d8e75a8d0 605 temp = 255;
dflet 0:400d8e75a8d0 606 newtbl[zigzag[i]] = (unsigned char) temp;
dflet 0:400d8e75a8d0 607 }
dflet 0:400d8e75a8d0 608
dflet 0:400d8e75a8d0 609 // write the resulting chrominance quant table to the output buffer
dflet 0:400d8e75a8d0 610 for (i=0; i<64; i++)
dflet 0:400d8e75a8d0 611 *pbuf++ = newtbl[i];
dflet 0:400d8e75a8d0 612
dflet 0:400d8e75a8d0 613 return (length+2);
dflet 0:400d8e75a8d0 614 }
dflet 0:400d8e75a8d0 615
dflet 0:400d8e75a8d0 616
dflet 0:400d8e75a8d0 617 //*****************************************************************************
dflet 0:400d8e75a8d0 618 //
dflet 0:400d8e75a8d0 619 //! DefineHuffmanTableMarkerDC
dflet 0:400d8e75a8d0 620 //!
dflet 0:400d8e75a8d0 621 //! \param1 pointer to Marker buffer
dflet 0:400d8e75a8d0 622 //! \param2 Huffman table
dflet 0:400d8e75a8d0 623 //! \param3 Class Identifier
dflet 0:400d8e75a8d0 624 //!
dflet 0:400d8e75a8d0 625 //! \return Length of the marker
dflet 0:400d8e75a8d0 626 //
dflet 0:400d8e75a8d0 627 //*****************************************************************************
dflet 0:400d8e75a8d0 628 static int DefineHuffmanTableMarkerDC(char *pbuf, unsigned int *htable, int class_id)
dflet 0:400d8e75a8d0 629 {
dflet 0:400d8e75a8d0 630 int i, l, count;
dflet 0:400d8e75a8d0 631 int length;
dflet 0:400d8e75a8d0 632 char *plength;
dflet 0:400d8e75a8d0 633
dflet 0:400d8e75a8d0 634 *pbuf++= 0xFF; // define huffman table marker
dflet 0:400d8e75a8d0 635 *pbuf++= 0xC4;
dflet 0:400d8e75a8d0 636 plength = pbuf; // place holder for length field
dflet 0:400d8e75a8d0 637 *pbuf++;
dflet 0:400d8e75a8d0 638 *pbuf++;
dflet 0:400d8e75a8d0 639 *pbuf++= class_id; // huffman table class | identifier
dflet 0:400d8e75a8d0 640
dflet 0:400d8e75a8d0 641 for (l = 0; l < 16; l++)
dflet 0:400d8e75a8d0 642 {
dflet 0:400d8e75a8d0 643 count = 0;
dflet 0:400d8e75a8d0 644 for (i = 0; i < 12; i++)
dflet 0:400d8e75a8d0 645 {
dflet 0:400d8e75a8d0 646 if ((htable[i] >> 8) == l)
dflet 0:400d8e75a8d0 647 count++;
dflet 0:400d8e75a8d0 648 }
dflet 0:400d8e75a8d0 649 *pbuf++= count; // number of huffman codes of length l+1
dflet 0:400d8e75a8d0 650 }
dflet 0:400d8e75a8d0 651
dflet 0:400d8e75a8d0 652 length = 19;
dflet 0:400d8e75a8d0 653 for (l = 0; l < 16; l++)
dflet 0:400d8e75a8d0 654 {
dflet 0:400d8e75a8d0 655 for (i = 0; i < 12; i++)
dflet 0:400d8e75a8d0 656 {
dflet 0:400d8e75a8d0 657 if ((htable[i] >> 8) == l)
dflet 0:400d8e75a8d0 658 {
dflet 0:400d8e75a8d0 659 *pbuf++= i; // HUFFVAL with huffman codes of length l+1
dflet 0:400d8e75a8d0 660 length++;
dflet 0:400d8e75a8d0 661 }
dflet 0:400d8e75a8d0 662 }
dflet 0:400d8e75a8d0 663 }
dflet 0:400d8e75a8d0 664
dflet 0:400d8e75a8d0 665 *plength++= length>>8; // length field
dflet 0:400d8e75a8d0 666 *plength = length&0xFF;
dflet 0:400d8e75a8d0 667
dflet 0:400d8e75a8d0 668 return (length + 2);
dflet 0:400d8e75a8d0 669 }
dflet 0:400d8e75a8d0 670
dflet 0:400d8e75a8d0 671
dflet 0:400d8e75a8d0 672 //*****************************************************************************
dflet 0:400d8e75a8d0 673 //
dflet 0:400d8e75a8d0 674 //! DefineHuffmanTableMarkerAC
dflet 0:400d8e75a8d0 675 //! 1. Establishes connection w/ AP//
dflet 0:400d8e75a8d0 676 //! 2. Initializes the camera sub-components//! GPIO Enable & Configuration
dflet 0:400d8e75a8d0 677 //! 3. Listens and processes the image capture requests from user-applications
dflet 0:400d8e75a8d0 678 //!
dflet 0:400d8e75a8d0 679 //! \param1 pointer to Marker buffer
dflet 0:400d8e75a8d0 680 //! \param2 Huffman table
dflet 0:400d8e75a8d0 681 //! \param3 Class Identifier
dflet 0:400d8e75a8d0 682 //!
dflet 0:400d8e75a8d0 683 //! \return Length of the Marker
dflet 0:400d8e75a8d0 684 //!
dflet 0:400d8e75a8d0 685 //
dflet 0:400d8e75a8d0 686 //*****************************************************************************
dflet 0:400d8e75a8d0 687 static int DefineHuffmanTableMarkerAC(char *pbuf, unsigned int *htable, int class_id)
dflet 0:400d8e75a8d0 688 {
dflet 0:400d8e75a8d0 689 int i, l, a, b, count;
dflet 0:400d8e75a8d0 690 char *plength;
dflet 0:400d8e75a8d0 691 int length;
dflet 0:400d8e75a8d0 692
dflet 0:400d8e75a8d0 693 *pbuf++= 0xFF; // define huffman table marker
dflet 0:400d8e75a8d0 694 *pbuf++= 0xC4;
dflet 0:400d8e75a8d0 695 plength = pbuf; // place holder for length field
dflet 0:400d8e75a8d0 696 *pbuf++;
dflet 0:400d8e75a8d0 697 *pbuf++;
dflet 0:400d8e75a8d0 698 *pbuf++= class_id; // huffman table class | identifier
dflet 0:400d8e75a8d0 699
dflet 0:400d8e75a8d0 700 for (l = 0; l < 16; l++)
dflet 0:400d8e75a8d0 701 {
dflet 0:400d8e75a8d0 702 count = 0;
dflet 0:400d8e75a8d0 703 for (i = 0; i < 162; i++)
dflet 0:400d8e75a8d0 704 {
dflet 0:400d8e75a8d0 705 if ((htable[i] >> 8) == l)
dflet 0:400d8e75a8d0 706 count++;
dflet 0:400d8e75a8d0 707 }
dflet 0:400d8e75a8d0 708
dflet 0:400d8e75a8d0 709 *pbuf++= count; // number of huffman codes of length l+1
dflet 0:400d8e75a8d0 710 }
dflet 0:400d8e75a8d0 711
dflet 0:400d8e75a8d0 712 length = 19;
dflet 0:400d8e75a8d0 713 for (l = 0; l < 16; l++)
dflet 0:400d8e75a8d0 714 {
dflet 0:400d8e75a8d0 715 // check EOB: 0|0
dflet 0:400d8e75a8d0 716 if ((htable[160] >> 8) == l)
dflet 0:400d8e75a8d0 717 {
dflet 0:400d8e75a8d0 718 *pbuf++= 0; // HUFFVAL with huffman codes of length l+1
dflet 0:400d8e75a8d0 719 length++;
dflet 0:400d8e75a8d0 720 }
dflet 0:400d8e75a8d0 721
dflet 0:400d8e75a8d0 722 // check HUFFVAL: 0|1 to E|A
dflet 0:400d8e75a8d0 723 for (i = 0; i < 150; i++)
dflet 0:400d8e75a8d0 724 {
dflet 0:400d8e75a8d0 725 if ((htable[i] >> 8) == l)
dflet 0:400d8e75a8d0 726 {
dflet 0:400d8e75a8d0 727 a = i/10;
dflet 0:400d8e75a8d0 728 b = i%10;
dflet 0:400d8e75a8d0 729 *pbuf++= (a<<4)|(b+1); // HUFFVAL with huffman codes of length l+1
dflet 0:400d8e75a8d0 730 length++;
dflet 0:400d8e75a8d0 731 }
dflet 0:400d8e75a8d0 732 }
dflet 0:400d8e75a8d0 733
dflet 0:400d8e75a8d0 734 // check ZRL: F|0
dflet 0:400d8e75a8d0 735 if ((htable[161] >> 8) == l)
dflet 0:400d8e75a8d0 736 {
dflet 0:400d8e75a8d0 737 *pbuf++= 0xF0; // HUFFVAL with huffman codes of length l+1
dflet 0:400d8e75a8d0 738 length++;
dflet 0:400d8e75a8d0 739 }
dflet 0:400d8e75a8d0 740
dflet 0:400d8e75a8d0 741 // check HUFFVAL: F|1 to F|A
dflet 0:400d8e75a8d0 742 for (i = 150; i < 160; i++)
dflet 0:400d8e75a8d0 743 {
dflet 0:400d8e75a8d0 744 if ((htable[i] >> 8) == l)
dflet 0:400d8e75a8d0 745 {
dflet 0:400d8e75a8d0 746 a = i/10;
dflet 0:400d8e75a8d0 747 b = i%10;
dflet 0:400d8e75a8d0 748 *pbuf++= (a<<4)|(b+1); // HUFFVAL with huffman codes of length l+1
dflet 0:400d8e75a8d0 749 length++;
dflet 0:400d8e75a8d0 750 }
dflet 0:400d8e75a8d0 751 }
dflet 0:400d8e75a8d0 752 }
dflet 0:400d8e75a8d0 753
dflet 0:400d8e75a8d0 754 *plength++= length>>8; // length field
dflet 0:400d8e75a8d0 755 *plength = length&0xFF;
dflet 0:400d8e75a8d0 756 return (length + 2);
dflet 0:400d8e75a8d0 757 }
dflet 0:400d8e75a8d0 758
dflet 0:400d8e75a8d0 759
dflet 0:400d8e75a8d0 760 //*****************************************************************************
dflet 0:400d8e75a8d0 761 //
dflet 0:400d8e75a8d0 762 //! DefineRestartIntervalMarker
dflet 0:400d8e75a8d0 763 //!
dflet 0:400d8e75a8d0 764 //! \param1 pointer to Marker buffer
dflet 0:400d8e75a8d0 765 //! \param2 return interval
dflet 0:400d8e75a8d0 766 //!
dflet 0:400d8e75a8d0 767 //! \return Length
dflet 0:400d8e75a8d0 768 //
dflet 0:400d8e75a8d0 769 //*****************************************************************************
dflet 0:400d8e75a8d0 770 static int DefineRestartIntervalMarker(char *pbuf, int ri)
dflet 0:400d8e75a8d0 771 {
dflet 0:400d8e75a8d0 772 *pbuf++= 0xFF; // define restart interval marker
dflet 0:400d8e75a8d0 773 *pbuf++= 0xDD;
dflet 0:400d8e75a8d0 774 *pbuf++= 0x00; // length
dflet 0:400d8e75a8d0 775 *pbuf++= 0x04;
dflet 0:400d8e75a8d0 776 *pbuf++= ri >> 8; // restart interval
dflet 0:400d8e75a8d0 777 *pbuf++= ri & 0xFF;
dflet 0:400d8e75a8d0 778 return 6;
dflet 0:400d8e75a8d0 779 }
dflet 0:400d8e75a8d0 780 //*****************************************************************************
dflet 0:400d8e75a8d0 781 //
dflet 0:400d8e75a8d0 782 //! CreateJpegHeader
dflet 0:400d8e75a8d0 783 //! Create JPEG Header in JFIF format
dflet 0:400d8e75a8d0 784 //!
dflet 0:400d8e75a8d0 785 //! \param1 header - pointer to JPEG header buffer
dflet 0:400d8e75a8d0 786 //! \param2 width - image width
dflet 0:400d8e75a8d0 787 //! \param3 height - image height
dflet 0:400d8e75a8d0 788 //! \param4 format - color format (0 = YCbCr422, 1 = YCbCr420, 2 = monochrome)
dflet 0:400d8e75a8d0 789 //! \param5 restart_int - restart marker interval
dflet 0:400d8e75a8d0 790 //! \param6 qscale - quantization table scaling factor
dflet 0:400d8e75a8d0 791 //!
dflet 0:400d8e75a8d0 792 //! \return length of JPEG header (bytes)
dflet 0:400d8e75a8d0 793 //
dflet 0:400d8e75a8d0 794 //*****************************************************************************
dflet 0:400d8e75a8d0 795
dflet 0:400d8e75a8d0 796 static int CreateJpegHeader(char *header, int width, int height,
dflet 0:400d8e75a8d0 797 int format, int restart_int, int qscale)
dflet 0:400d8e75a8d0 798 {
dflet 0:400d8e75a8d0 799 char *pbuf = header;
dflet 0:400d8e75a8d0 800 int length;
dflet 0:400d8e75a8d0 801
dflet 0:400d8e75a8d0 802 // SOI
dflet 0:400d8e75a8d0 803 *pbuf++= 0xFF;
dflet 0:400d8e75a8d0 804 *pbuf++= 0xD8;
dflet 0:400d8e75a8d0 805 length = 2;
dflet 0:400d8e75a8d0 806
dflet 0:400d8e75a8d0 807 // JFIF APP0
dflet 0:400d8e75a8d0 808 length += JfifApp0Marker(pbuf);
dflet 0:400d8e75a8d0 809
dflet 0:400d8e75a8d0 810 // Quantization Tables
dflet 0:400d8e75a8d0 811 pbuf = header + length;
dflet 0:400d8e75a8d0 812 length += DefineQuantizationTableMarker((unsigned char *)pbuf, qscale, format);
dflet 0:400d8e75a8d0 813
dflet 0:400d8e75a8d0 814 // Frame Header
dflet 0:400d8e75a8d0 815 pbuf = header + length;
dflet 0:400d8e75a8d0 816 length += FrameHeaderMarker(pbuf, width, height, format);
dflet 0:400d8e75a8d0 817
dflet 0:400d8e75a8d0 818 // Huffman Table DC 0 for Luma
dflet 0:400d8e75a8d0 819 pbuf = header + length;
dflet 0:400d8e75a8d0 820 length += DefineHuffmanTableMarkerDC(pbuf, &JPEG_StdHuffmanTbl[352], 0x00);
dflet 0:400d8e75a8d0 821
dflet 0:400d8e75a8d0 822 // Huffman Table AC 0 for Luma
dflet 0:400d8e75a8d0 823 pbuf = header + length;
dflet 0:400d8e75a8d0 824 length += DefineHuffmanTableMarkerAC(pbuf, &JPEG_StdHuffmanTbl[0], 0x10);
dflet 0:400d8e75a8d0 825
dflet 0:400d8e75a8d0 826 if (format != FORMAT_MONOCHROME)// YCbCr
dflet 0:400d8e75a8d0 827 {
dflet 0:400d8e75a8d0 828 // Huffman Table DC 1 for Chroma
dflet 0:400d8e75a8d0 829 pbuf = header + length;
dflet 0:400d8e75a8d0 830 length += DefineHuffmanTableMarkerDC(pbuf, &JPEG_StdHuffmanTbl[368], 0x01);
dflet 0:400d8e75a8d0 831
dflet 0:400d8e75a8d0 832 // Huffman Table AC 1 for Chroma
dflet 0:400d8e75a8d0 833 pbuf = header + length;
dflet 0:400d8e75a8d0 834 length += DefineHuffmanTableMarkerAC(pbuf, &JPEG_StdHuffmanTbl[176], 0x11);
dflet 0:400d8e75a8d0 835 }
dflet 0:400d8e75a8d0 836
dflet 0:400d8e75a8d0 837 // Restart Interval
dflet 0:400d8e75a8d0 838 if (restart_int > 0)
dflet 0:400d8e75a8d0 839 {
dflet 0:400d8e75a8d0 840 pbuf = header + length;
dflet 0:400d8e75a8d0 841 length += DefineRestartIntervalMarker(pbuf, restart_int);
dflet 0:400d8e75a8d0 842 }
dflet 0:400d8e75a8d0 843
dflet 0:400d8e75a8d0 844 // Scan Header
dflet 0:400d8e75a8d0 845 pbuf = header + length;
dflet 0:400d8e75a8d0 846 length += ScanHeaderMarker(pbuf, format);
dflet 0:400d8e75a8d0 847
dflet 0:400d8e75a8d0 848 return length;
dflet 0:400d8e75a8d0 849 }
dflet 0:400d8e75a8d0 850 #endif// jpeg defined
dflet 0:400d8e75a8d0 851
dflet 0:400d8e75a8d0 852
dflet 0:400d8e75a8d0 853
dflet 0:400d8e75a8d0 854 //*****************************************************************************
dflet 0:400d8e75a8d0 855 //
dflet 0:400d8e75a8d0 856 // Close the Doxygen group.
dflet 0:400d8e75a8d0 857 //! @}
dflet 0:400d8e75a8d0 858 //
dflet 0:400d8e75a8d0 859 //*****************************************************************************
dflet 0:400d8e75a8d0 860