This is an digital video camera program using NKK\'s oLED swtich and 4D Systems\' uCam serial camera. It takes image from the uCam and displays on the IS-C15 switch. Some image processing demos are included. This program uses FatFileSytem, SDFileSystem, and TextLCD library. See http://www.youtube.com/watch?v=fqHTaCRHyQs for how it works. CQ出版社の「mbed/ARM活用事例」第10章シリアル接続カメラと有機ELディスプレイ内蔵スイッチで作るmbedディジタル・カメラの作例です。動作の様子は http://www.youtube.com/watch?v=fqHTaCRHyQs で見れます。

Dependencies:   TextLCD mbed SDFileSystem

Committer:
non
Date:
Thu Oct 13 02:41:04 2011 +0000
Revision:
2:0621feb3adf2
Parent:
0:07d02a20d1cc

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
non 0:07d02a20d1cc 1 /* This software is an digital video camera program using NKK's oLED swtich
non 0:07d02a20d1cc 2 * and 4D Systems' uCam serial camera. It takes image from the uCam and
non 0:07d02a20d1cc 3 * displays on the IS-C15 switch. Some image processing demos are included.
non 0:07d02a20d1cc 4 *
non 0:07d02a20d1cc 5 * This program uses FatFileSytem, SDFileSystem, and TextLCD library.
non 0:07d02a20d1cc 6 *
non 0:07d02a20d1cc 7 * Copyright (c) 2011, Noriaki Mitsunaga
non 0:07d02a20d1cc 8 *
non 0:07d02a20d1cc 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
non 0:07d02a20d1cc 10 * of this software and associated documentation files (the "Software"), to deal
non 0:07d02a20d1cc 11 * in the Software without restriction, including without limitation the rights
non 0:07d02a20d1cc 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
non 0:07d02a20d1cc 13 * copies of the Software, and to permit persons to whom the Software is
non 0:07d02a20d1cc 14 * furnished to do so, subject to the following conditions:
non 0:07d02a20d1cc 15 *
non 0:07d02a20d1cc 16 * The above copyright notice and this permission notice shall be included in
non 0:07d02a20d1cc 17 * all copies or substantial portions of the Software.
non 0:07d02a20d1cc 18 *
non 0:07d02a20d1cc 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
non 0:07d02a20d1cc 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
non 0:07d02a20d1cc 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
non 0:07d02a20d1cc 22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
non 0:07d02a20d1cc 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
non 0:07d02a20d1cc 24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
non 0:07d02a20d1cc 25 * THE SOFTWARE.
non 0:07d02a20d1cc 26 */
non 0:07d02a20d1cc 27 #include "mbed.h"
non 0:07d02a20d1cc 28 // #define USE_LCD // Need this if you want to use text LCD
non 0:07d02a20d1cc 29 #ifdef USE_LCD
non 0:07d02a20d1cc 30 #include "TextLCD.h"
non 0:07d02a20d1cc 31 #endif
non 0:07d02a20d1cc 32 // #include "SDFileSystem.h" // Need this if you want to save to SD-Card
non 0:07d02a20d1cc 33
non 0:07d02a20d1cc 34 #include "isc15.h"
non 0:07d02a20d1cc 35 #include "ucam.h"
non 0:07d02a20d1cc 36
non 0:07d02a20d1cc 37 // SDFileSystem sd(p5, p6, p7, p8, "sd"); // Need this if you want to save to SD-Card
non 0:07d02a20d1cc 38 LocalFileSystem local("local"); // Need this if you want to save to local flash
non 0:07d02a20d1cc 39 SPI spi(p11, p12, p13); // mosi(SDO), miso(SDI), sclk(SCLK)
non 0:07d02a20d1cc 40
non 0:07d02a20d1cc 41 ISC15 ISC15(p16, p15, p14, p18); // NKK IS-C15 oLED swtich
non 0:07d02a20d1cc 42 DigitalOut led1(LED1), led2(LED2); // On board LEDs
non 0:07d02a20d1cc 43 DigitalIn sw1(p17); // Shutter switch (IS-C15)
non 0:07d02a20d1cc 44 uCam ucam(p9, p10); // uCam-TTL (p9=TX, p10=RX)
non 0:07d02a20d1cc 45
non 0:07d02a20d1cc 46 Ticker timer;
non 0:07d02a20d1cc 47 bool sw1pressed = false;
non 0:07d02a20d1cc 48 bool sw1pressing = false;
non 0:07d02a20d1cc 49
non 0:07d02a20d1cc 50 #ifdef USE_LCD
non 0:07d02a20d1cc 51 TextLCD lcd(p24, p26, p27, p28, p29, p30); // rs, e, d0-d3
non 0:07d02a20d1cc 52 #define LCDPRINTF(...) lcd.printf(__VA_ARGS__)
non 0:07d02a20d1cc 53 #else
non 0:07d02a20d1cc 54 #define LCDPRINTF(...)
non 0:07d02a20d1cc 55 #endif /* USE_LCD */
non 0:07d02a20d1cc 56
non 0:07d02a20d1cc 57 /* Function prototypes */
non 0:07d02a20d1cc 58 void checkSW();
non 0:07d02a20d1cc 59 int SaveJPEG(const char *fname);
non 0:07d02a20d1cc 60
non 0:07d02a20d1cc 61 /* main fuction */
non 0:07d02a20d1cc 62 int main() {
non 0:07d02a20d1cc 63 unsigned char cam[80*60*2];
non 0:07d02a20d1cc 64 unsigned char oled[64*48*2];
non 0:07d02a20d1cc 65 int n = 0;
non 0:07d02a20d1cc 66
non 0:07d02a20d1cc 67 sw1.mode(PullUp);
non 0:07d02a20d1cc 68 led1 = led2 = 1;
non 0:07d02a20d1cc 69 // Setup the spi for 8 bit data, high steady state clock,
non 0:07d02a20d1cc 70 // second edge capture, with a 4MHz clock rate
non 0:07d02a20d1cc 71 spi.format(8, 3);
non 0:07d02a20d1cc 72 spi.frequency(4000000);
non 0:07d02a20d1cc 73 // Initialize IS Color 15's oLED
non 0:07d02a20d1cc 74 ISC15.Init(ISC15_DEVICE_ISC15, &spi);
non 0:07d02a20d1cc 75 // Clear oLED display
non 0:07d02a20d1cc 76 ISC15.Cls();
non 0:07d02a20d1cc 77
non 0:07d02a20d1cc 78 // Initialize uCam-TTL
non 0:07d02a20d1cc 79 LCDPRINTF("Init Camera..\n");
non 0:07d02a20d1cc 80 if (!ucam.Init()) {
non 0:07d02a20d1cc 81 LCDPRINTF("Init failed.\n");
non 0:07d02a20d1cc 82 goto ERROR;
non 0:07d02a20d1cc 83 }
non 0:07d02a20d1cc 84 // Set AC frequency (60 for Kansai-area, 50 for Kanto-area)
non 0:07d02a20d1cc 85 if (!ucam.LightFreq(60))
non 0:07d02a20d1cc 86 goto ERROR;
non 0:07d02a20d1cc 87 // Attach tick timer to checkSW function
non 0:07d02a20d1cc 88 timer.attach_us(checkSW, 20000);
non 0:07d02a20d1cc 89
non 0:07d02a20d1cc 90 LCDPRINTF("Starting.\n");
non 0:07d02a20d1cc 91 led1 = led2 = 0;
non 0:07d02a20d1cc 92
non 0:07d02a20d1cc 93 for (;;) {
non 0:07d02a20d1cc 94 // Flush LED
non 0:07d02a20d1cc 95 led1 = 1;
non 0:07d02a20d1cc 96 wait(0.1);
non 0:07d02a20d1cc 97 led1 = 0;
non 0:07d02a20d1cc 98
non 0:07d02a20d1cc 99 #if 1 /* D1: Set 1 to test RGB565 mode */
non 0:07d02a20d1cc 100 if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_RGB565, UCAM_RAW_RESOLUTION_80X60, cam))
non 0:07d02a20d1cc 101 goto ERROR;
non 0:07d02a20d1cc 102
non 0:07d02a20d1cc 103 for (int y=0; y<48; y++) {
non 0:07d02a20d1cc 104 unsigned char *rg = cam + (80-64)/2 + ((60-48)/2+y)*80*2;
non 0:07d02a20d1cc 105 unsigned char *gb = rg + 1;
non 0:07d02a20d1cc 106 unsigned char *p = oled + y*64*2;
non 0:07d02a20d1cc 107 for (int x=0; x<64; x++, rg+=2, gb+=2) {
non 0:07d02a20d1cc 108 *p ++ = (*gb <<3) | (*rg & 0x7);
non 0:07d02a20d1cc 109 *p ++ = (*gb & 0xe0) | (*rg >> 3);
non 0:07d02a20d1cc 110 }
non 0:07d02a20d1cc 111 }
non 0:07d02a20d1cc 112 ISC15.Disp(ISC15_DSPMODE_64K, oled);
non 0:07d02a20d1cc 113 #endif
non 0:07d02a20d1cc 114
non 0:07d02a20d1cc 115 #if 0 /* D2: Set 1 to test 4bit gray mode */
non 0:07d02a20d1cc 116 if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_4BITG, UCAM_RAW_RESOLUTION_80X60, cam))
non 0:07d02a20d1cc 117 goto ERROR;
non 0:07d02a20d1cc 118
non 0:07d02a20d1cc 119 for (int y=0; y<48; y++) {
non 0:07d02a20d1cc 120 unsigned char *v = cam + ((80-64)/2 + ((60-48)/2+y)*80)/2;
non 0:07d02a20d1cc 121 unsigned char *p = oled + y*64*2;
non 0:07d02a20d1cc 122 for (int x=0; x<64; x++, v++) {
non 0:07d02a20d1cc 123 int V = (*v & 0xf0) >> 4;
non 0:07d02a20d1cc 124 *p ++ = (V << 4) | (V >> 1);
non 0:07d02a20d1cc 125 *p ++ = ((V << 2) & 0xe0) | (V << 1);
non 0:07d02a20d1cc 126 x ++;
non 0:07d02a20d1cc 127
non 0:07d02a20d1cc 128 V = *v & 0xf;
non 0:07d02a20d1cc 129 *p ++ = (V << 4) | (V >> 1);
non 0:07d02a20d1cc 130 *p ++ = ((V << 2) & 0xe0) | (V << 1);
non 0:07d02a20d1cc 131 }
non 0:07d02a20d1cc 132 }
non 0:07d02a20d1cc 133 ISC15.Disp(ISC15_DSPMODE_64K, oled);
non 0:07d02a20d1cc 134 #endif
non 0:07d02a20d1cc 135
non 0:07d02a20d1cc 136 #if 0 /* D3: Set 1 to test 8bit gray mode */
non 0:07d02a20d1cc 137 if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_8BITG, UCAM_RAW_RESOLUTION_80X60, cam))
non 0:07d02a20d1cc 138 goto ERROR;
non 0:07d02a20d1cc 139
non 0:07d02a20d1cc 140 for (int y=0; y<48; y++) {
non 0:07d02a20d1cc 141 unsigned char *v = cam + (80-64)/2 + ((60-48)/2+y)*80;
non 0:07d02a20d1cc 142 unsigned char *p = oled + y*64*2;
non 0:07d02a20d1cc 143 for (int x=0; x<64; x++, v++) {
non 0:07d02a20d1cc 144 *p ++ = (*v & 0xf8) | (*v >> 5);
non 0:07d02a20d1cc 145 *p ++ = ((*v << 3) & 0xe0) | (*v >> 3);
non 0:07d02a20d1cc 146 }
non 0:07d02a20d1cc 147 }
non 0:07d02a20d1cc 148 ISC15.Disp(ISC15_DSPMODE_64K, oled);
non 0:07d02a20d1cc 149 #endif
non 0:07d02a20d1cc 150
non 0:07d02a20d1cc 151 #if 0 /* D4: Set 1 to test RGB332 mode */
non 0:07d02a20d1cc 152 if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_RGB332, UCAM_RAW_RESOLUTION_80X60, cam))
non 0:07d02a20d1cc 153 goto ERROR;
non 0:07d02a20d1cc 154
non 0:07d02a20d1cc 155 for (int y=0; y<48; y++) {
non 0:07d02a20d1cc 156 unsigned char *v = cam + ((80-64)/2 + ((60-48)/2+y)*80);
non 0:07d02a20d1cc 157 unsigned char *p = oled + y*64*2;
non 0:07d02a20d1cc 158 for (int x=0; x<64; x++, v++) {
non 0:07d02a20d1cc 159 int B = (*v & 0xe0) >> 5; /* 3bits */
non 0:07d02a20d1cc 160 int G = (*v & 0x1c) >> 3; /* 3bits */
non 0:07d02a20d1cc 161 int R = (*v & 0x3); /* 2bits */
non 0:07d02a20d1cc 162 *p ++ = (B << 6) | G;
non 0:07d02a20d1cc 163 *p ++ = R << 2;
non 0:07d02a20d1cc 164 }
non 0:07d02a20d1cc 165 }
non 0:07d02a20d1cc 166 ISC15.Disp(ISC15_DSPMODE_64K, oled);
non 0:07d02a20d1cc 167 #endif
non 0:07d02a20d1cc 168
non 0:07d02a20d1cc 169 #if 0 /* D5: Set 1 to test cropping (digital zoom) */
non 0:07d02a20d1cc 170 if (!ucam.SnapshotRawCrop(UCAM_COLOR_TYPE_RGB565,
non 0:07d02a20d1cc 171 UCAM_RAW_RESOLUTION_160X120, 48, 36, 64, 48, cam))
non 0:07d02a20d1cc 172 goto ERROR;
non 0:07d02a20d1cc 173
non 0:07d02a20d1cc 174 unsigned char *rg = cam;
non 0:07d02a20d1cc 175 unsigned char *gb = rg + 1;
non 0:07d02a20d1cc 176 unsigned char *p = oled;
non 0:07d02a20d1cc 177 for (int i=64*48; i>0; i--, rg+=2, gb+=2) {
non 0:07d02a20d1cc 178 *p ++ = (*gb <<3) | (*rg & 0x7);
non 0:07d02a20d1cc 179 *p ++ = (*gb & 0xe0) | (*rg >> 3);
non 0:07d02a20d1cc 180 }
non 0:07d02a20d1cc 181 ISC15.Disp(ISC15_DSPMODE_64K, oled);
non 0:07d02a20d1cc 182 #endif
non 0:07d02a20d1cc 183
non 0:07d02a20d1cc 184 #if 0 /* D6: Set 1 to test 8bit gray differential image */
non 0:07d02a20d1cc 185 unsigned char cam2[80*60];
non 0:07d02a20d1cc 186 static unsigned char *camp = cam, *cam2p = cam2;
non 0:07d02a20d1cc 187
non 0:07d02a20d1cc 188 if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_8BITG, UCAM_RAW_RESOLUTION_80X60, camp))
non 0:07d02a20d1cc 189 goto ERROR;
non 0:07d02a20d1cc 190
non 0:07d02a20d1cc 191 for (int y=0; y<48; y++) {
non 0:07d02a20d1cc 192 unsigned char *v = camp + (80-64)/2 + ((60-48)/2+y)*80;
non 0:07d02a20d1cc 193 unsigned char *b = cam2p + (80-64)/2 + ((60-48)/2+y)*80;
non 0:07d02a20d1cc 194 unsigned char *p = oled + y*64*2;
non 0:07d02a20d1cc 195
non 0:07d02a20d1cc 196 for (int x=0; x<64; x++, v++, b++) {
non 0:07d02a20d1cc 197 if (abs(*v-*b)>10) {
non 0:07d02a20d1cc 198 *p ++ = (*v & 0xf8) | (*v >> 5);
non 0:07d02a20d1cc 199 *p ++ = ((*v << 3) & 0xe0) | (*v >> 3);
non 0:07d02a20d1cc 200 } else {
non 0:07d02a20d1cc 201 *p ++ = 0;
non 0:07d02a20d1cc 202 *p ++ = 0;
non 0:07d02a20d1cc 203 }
non 0:07d02a20d1cc 204 }
non 0:07d02a20d1cc 205 }
non 0:07d02a20d1cc 206 if (camp == cam) {
non 0:07d02a20d1cc 207 camp = cam2;
non 0:07d02a20d1cc 208 cam2p = cam;
non 0:07d02a20d1cc 209 } else {
non 0:07d02a20d1cc 210 camp = cam;
non 0:07d02a20d1cc 211 cam2p = cam2;
non 0:07d02a20d1cc 212 }
non 0:07d02a20d1cc 213 ISC15.Disp(ISC15_DSPMODE_64K, oled);
non 0:07d02a20d1cc 214 #endif
non 0:07d02a20d1cc 215
non 0:07d02a20d1cc 216 #if 0 /* D7: Set 1 to show RGB565 image when images' differential is large */
non 0:07d02a20d1cc 217 unsigned char cam2[80*60*2];
non 0:07d02a20d1cc 218 static unsigned char *camp = cam, *cam2p = cam2;
non 0:07d02a20d1cc 219
non 0:07d02a20d1cc 220 if (!ucam.SnapshotRawCrop(UCAM_COLOR_TYPE_RGB565,
non 0:07d02a20d1cc 221 UCAM_RAW_RESOLUTION_80X60, 8, 6, 64, 48, camp))
non 0:07d02a20d1cc 222 goto ERROR;
non 0:07d02a20d1cc 223
non 0:07d02a20d1cc 224 unsigned char *rg = camp;
non 0:07d02a20d1cc 225 unsigned char *gb = rg + 1;
non 0:07d02a20d1cc 226 unsigned char *rg0 = cam2p;
non 0:07d02a20d1cc 227 unsigned char *gb0 = rg0 + 1;
non 0:07d02a20d1cc 228 unsigned int diff = 0;
non 0:07d02a20d1cc 229
non 0:07d02a20d1cc 230 for (int i=64*48; i>0; i--, rg+=2, gb+=2, rg0+=2, gb0+=2)
non 0:07d02a20d1cc 231 diff += abs(((*rg & 0x7)<<3 | (*gb >> 5))-((*rg0 & 0x7)<<3 | (*gb0>> 5)));
non 0:07d02a20d1cc 232 LCDPRINTF("d: %d.\n", diff);
non 0:07d02a20d1cc 233
non 0:07d02a20d1cc 234 if (diff > 3000) {
non 0:07d02a20d1cc 235 rg = camp;
non 0:07d02a20d1cc 236 gb = rg + 1;
non 0:07d02a20d1cc 237 unsigned char *p = oled;
non 0:07d02a20d1cc 238 for (int i=64*48; i>0; i--, rg+=2, gb+=2) {
non 0:07d02a20d1cc 239 *p ++ = (*gb <<3) | (*rg & 0x7);
non 0:07d02a20d1cc 240 *p ++ = (*gb & 0xe0) | (*rg >> 3);
non 0:07d02a20d1cc 241 }
non 0:07d02a20d1cc 242 ISC15.Disp(ISC15_DSPMODE_64K, oled);
non 0:07d02a20d1cc 243 } else {
non 0:07d02a20d1cc 244 ISC15.Cls();
non 0:07d02a20d1cc 245 }
non 0:07d02a20d1cc 246 if (camp == cam) {
non 0:07d02a20d1cc 247 camp = cam2;
non 0:07d02a20d1cc 248 cam2p = cam;
non 0:07d02a20d1cc 249 } else {
non 0:07d02a20d1cc 250 camp = cam;
non 0:07d02a20d1cc 251 cam2p = cam2;
non 0:07d02a20d1cc 252 }
non 0:07d02a20d1cc 253 #endif
non 0:07d02a20d1cc 254
non 0:07d02a20d1cc 255 if (sw1pressed) {
non 0:07d02a20d1cc 256 char fname[20];
non 0:07d02a20d1cc 257 // sprintf(fname, "/sd/%05d.jpg", n); // Save to SD-Card
non 0:07d02a20d1cc 258 sprintf(fname, "/local/%05d.jpg", n); // Save to local flash memory
non 0:07d02a20d1cc 259 LCDPRINTF("Saving image\n");
non 0:07d02a20d1cc 260 SaveJPEG(fname);
non 0:07d02a20d1cc 261 LCDPRINTF("DONE \n");
non 0:07d02a20d1cc 262 n ++;
non 0:07d02a20d1cc 263 sw1pressed = false;
non 0:07d02a20d1cc 264 led2 = 0;
non 0:07d02a20d1cc 265 }
non 0:07d02a20d1cc 266 }
non 0:07d02a20d1cc 267
non 0:07d02a20d1cc 268 ERROR:
non 0:07d02a20d1cc 269 LCDPRINTF("ERROR\n");
non 0:07d02a20d1cc 270 while (1) {
non 0:07d02a20d1cc 271 led1 = 1;
non 0:07d02a20d1cc 272 wait(0.1);
non 0:07d02a20d1cc 273 led1 = 0;
non 0:07d02a20d1cc 274 wait(0.1);
non 0:07d02a20d1cc 275 }
non 0:07d02a20d1cc 276 }
non 0:07d02a20d1cc 277
non 0:07d02a20d1cc 278 /* ------------------------------------------ */
non 0:07d02a20d1cc 279 /* Check current status of the switch */
non 0:07d02a20d1cc 280 /* The fuction is called by 20ms timer */
non 0:07d02a20d1cc 281 /* ------------------------------------------ */
non 0:07d02a20d1cc 282 void checkSW() {
non 0:07d02a20d1cc 283 if (sw1 == 0) {
non 0:07d02a20d1cc 284 /* Swtich is pressed */
non 0:07d02a20d1cc 285 sw1pressed = true;
non 0:07d02a20d1cc 286 sw1pressing = true;
non 0:07d02a20d1cc 287 led2 = 1;
non 0:07d02a20d1cc 288 } else {
non 0:07d02a20d1cc 289 /* Switch is open */
non 0:07d02a20d1cc 290 sw1pressing = false;
non 0:07d02a20d1cc 291 led2 = 0;
non 0:07d02a20d1cc 292 }
non 0:07d02a20d1cc 293 }
non 0:07d02a20d1cc 294
non 0:07d02a20d1cc 295 /* ------------------------------------------ */
non 0:07d02a20d1cc 296 /* Save a JPEG image read from uCam to a file */
non 0:07d02a20d1cc 297 /* ------------------------------------------ */
non 0:07d02a20d1cc 298 int SaveJPEG(const char *fname) {
non 0:07d02a20d1cc 299 /* Open file */
non 0:07d02a20d1cc 300 FILE *fp = fopen(fname, "wb");
non 0:07d02a20d1cc 301 if (fp == NULL) {
non 0:07d02a20d1cc 302 LCDPRINTF("XXX %s\n", fname);
non 0:07d02a20d1cc 303 return 0;
non 0:07d02a20d1cc 304 }
non 0:07d02a20d1cc 305
non 0:07d02a20d1cc 306 /* Prepare to recieve JPEG image */
non 0:07d02a20d1cc 307 int sz = ucam.SnapshotJPEGi(UCAM_JPEG_RESOLUTION_320X240, 512);
non 0:07d02a20d1cc 308 if (sz == 0)
non 0:07d02a20d1cc 309 return 0;
non 0:07d02a20d1cc 310
non 0:07d02a20d1cc 311 /* Recieve packets */
non 0:07d02a20d1cc 312 int pno = 0;
non 0:07d02a20d1cc 313 unsigned char cam[512];
non 0:07d02a20d1cc 314 while (sz > 0) {
non 0:07d02a20d1cc 315 int pksz = 512;
non 0:07d02a20d1cc 316 led2 = ~led2;
non 0:07d02a20d1cc 317
non 0:07d02a20d1cc 318 if (sz < (512 - 6))
non 0:07d02a20d1cc 319 pksz = sz + 6;
non 0:07d02a20d1cc 320 LCDPRINTF("%d %d\n", pno, pksz);
non 0:07d02a20d1cc 321 /* Recieve a packet */
non 0:07d02a20d1cc 322 if (!ucam.SnapshotJPEGd(pno, cam, pksz)) {
non 0:07d02a20d1cc 323 if (fp != NULL)
non 0:07d02a20d1cc 324 fclose(fp);
non 0:07d02a20d1cc 325 return 0;
non 0:07d02a20d1cc 326 }
non 0:07d02a20d1cc 327 /* Write the packet */
non 0:07d02a20d1cc 328 if (fp != NULL)
non 0:07d02a20d1cc 329 fwrite(cam + 4, 1, pksz - 6, fp);
non 0:07d02a20d1cc 330 sz -= (pksz - 6);
non 0:07d02a20d1cc 331 pno ++;
non 0:07d02a20d1cc 332 /* Check end of the image */
non 0:07d02a20d1cc 333 if (sz == 0) {
non 0:07d02a20d1cc 334 if (pksz == 512) {
non 0:07d02a20d1cc 335 // Send reset command as manual says
non 0:07d02a20d1cc 336 wait_ms(3);
non 0:07d02a20d1cc 337 ucam.Reset();
non 0:07d02a20d1cc 338 ucam.Init();
non 0:07d02a20d1cc 339 } else {
non 0:07d02a20d1cc 340 ucam.ACK_F0F0();
non 0:07d02a20d1cc 341 }
non 0:07d02a20d1cc 342 }
non 0:07d02a20d1cc 343 }
non 0:07d02a20d1cc 344 fclose(fp);
non 0:07d02a20d1cc 345
non 0:07d02a20d1cc 346 return 1;
non 0:07d02a20d1cc 347 }