fork of Camera_LS_Y201 lib supporting the 2MP variant/successor
Fork of Camera_LS_Y201 by
Camera_LS_Y201.cpp
00001 /** 00002 * ============================================================================= 00003 * LS-Y201 device driver class (Version 0.0.1) 00004 * Reference documents: LinkSprite JPEG Color Camera Serial UART Interface 00005 * January 2010 00006 * ============================================================================= 00007 * Copyright (c) 2010 Shinichiro Nakamura (CuBeatSystems) 00008 * 00009 * Permission is hereby granted, free of charge, to any person obtaining a copy 00010 * of this software and associated documentation files (the "Software"), to deal 00011 * in the Software without restriction, including without limitation the rights 00012 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00013 * copies of the Software, and to permit persons to whom the Software is 00014 * furnished to do so, subject to the following conditions: 00015 * 00016 * The above copyright notice and this permission notice shall be included in 00017 * all copies or substantial portions of the Software. 00018 * 00019 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00020 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00021 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00022 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00023 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00024 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00025 * THE SOFTWARE. 00026 * ============================================================================= 00027 */ 00028 00029 #include "Camera_LS_Y201.h" 00030 00031 #define TMOUT 2000 00032 00033 /** 00034 * Create. 00035 * 00036 * @param tx Transmitter. 00037 * @param rx Receiver. 00038 */ 00039 Camera_LS_Y201::Camera_LS_Y201(PinName tx, PinName rx) : serial(tx, rx) 00040 { 00041 serial.baud(115200); 00042 } 00043 00044 /** 00045 * Dispose. 00046 */ 00047 Camera_LS_Y201::~Camera_LS_Y201() 00048 { 00049 } 00050 00051 /** 00052 * Reset module. 00053 * 00054 * @return Error code. 00055 */ 00056 Camera_LS_Y201::ErrorCode Camera_LS_Y201::reset() 00057 { 00058 uint8_t send[4] = { 00059 0x56, 00060 0x00, 00061 0x26, 00062 0x00 00063 }; 00064 //uint8_t recv[50]; 00065 00066 const int nBauds = 5; 00067 const int bauds[nBauds] = {38400,57600,115200,128000,256000}; 00068 for(int i=0; i<nBauds; ++i) { 00069 printf("Reset @ %d baud: ",bauds[i]); 00070 serial.baud(bauds[i]); 00071 waitIdle(); 00072 if (!sendBytes(send, sizeof(send), 200 * TMOUT)) { 00073 printf("TxKO\n"); 00074 continue; 00075 } else { 00076 printf("TxOK "); 00077 } 00078 00079 //serial.baud(115200); 00080 00081 ErrorCode r = waitInitEnd(); 00082 if (r != NoError) { 00083 printf("RxKO\n"); 00084 continue; 00085 } else { 00086 printf("RxOK ...4s...\n"); 00087 wait(4); 00088 return NoError; 00089 } 00090 } 00091 return UnexpectedReply; 00092 /* 00093 if (!recvBytes(recv, sizeof(recv), 200 * TMOUT)) { 00094 return RecvError; 00095 } 00096 if ((recv[0] == 0x76) 00097 && (recv[1] == 0x00) 00098 && (recv[2] == 0x26) 00099 && (recv[3] == 0x00)) { 00100 ErrorCode r = waitInitEnd(); 00101 if (r != NoError) { 00102 return r; 00103 } 00104 wait(4); 00105 return NoError; 00106 } else { 00107 printf("%X %X %X %X\n",recv[0],recv[1],recv[2],recv[3]); 00108 return UnexpectedReply; 00109 } 00110 */ 00111 } 00112 00113 /** 00114 * Set image size. 00115 * 00116 * @param is Image size. 00117 * @return Error code. 00118 */ 00119 Camera_LS_Y201::ErrorCode Camera_LS_Y201::setImageSize(ImageSize is) 00120 { 00121 uint8_t send[5] = { 00122 0x56, 00123 0x00, 00124 0x54, 00125 0x01, 00126 0x00 // 0x11:320x240, 0x00:640x480, 0x22:160x120 00127 }; 00128 uint8_t recv[5]; 00129 switch (is) { 00130 case ImageSize160x120: 00131 send[4] = 0x22; 00132 break; 00133 case ImageSize320x240: 00134 send[4] = 0x11; 00135 break; 00136 case ImageSize640x480: 00137 send[4] = 0x00; 00138 break; 00139 case ImageSize800x600: 00140 send[4] = 0x1d; 00141 break; 00142 case ImageSize1024x768: 00143 send[4] = 0x1c; 00144 break; 00145 case ImageSize1280x960: 00146 send[4] = 0x1b; 00147 break; 00148 case ImageSize1600x1200: 00149 send[4] = 0x21; 00150 break; 00151 default: 00152 return InvalidArguments; 00153 } 00154 if (!sendBytes(send, sizeof(send), 200 * TMOUT)) { 00155 return SendError; 00156 } 00157 if (!recvBytes(recv, sizeof(recv), 200 * TMOUT)) { 00158 return RecvError; 00159 } 00160 if ((recv[0] == 0x76) 00161 && (recv[1] == 0x00) 00162 && (recv[2] == 0x54) 00163 && (recv[3] == 0x00) 00164 && (recv[4] == 0x00)) { 00165 wait(1); 00166 //return reset(); 00167 return NoError; 00168 } else { 00169 return UnexpectedReply; 00170 } 00171 } 00172 00173 00174 00175 Camera_LS_Y201::ErrorCode Camera_LS_Y201::setCompressionRatio(int cr) 00176 { 00177 uint8_t send[9] = { 00178 0x56, 00179 0x00, 00180 0x31, 00181 0x05, 00182 0x01, 00183 0x01, 00184 0x12, 00185 0x04, 00186 cr 00187 }; 00188 uint8_t recv[5]; 00189 00190 //printf("Setting Img-Qual to %d\n", cr); 00191 00192 if (!sendBytes(send, sizeof(send), 200 * TMOUT)) { 00193 return SendError; 00194 } 00195 if (!recvBytes(recv, sizeof(recv), 200 * TMOUT)) { 00196 return RecvError; 00197 } 00198 if ((recv[0] == 0x76) 00199 && (recv[1] == 0x00) 00200 && (recv[2] == 0x31) 00201 && (recv[3] == 0x00) 00202 && (recv[4] == 0x00)) { 00203 wait(1); 00204 //return reset(); 00205 return NoError; 00206 } else { 00207 return UnexpectedReply; 00208 } 00209 } 00210 00211 Camera_LS_Y201::ErrorCode Camera_LS_Y201::setBaudRate(Camera_LS_Y201::BaudRate br) 00212 { 00213 uint8_t send[6] = { 00214 0x56, 00215 0x00, 00216 0x24, 00217 0x03, 00218 0x01, 00219 br 00220 }; 00221 uint8_t recv[5]; 00222 00223 if (!sendBytes(send, sizeof(send), 200 * TMOUT)) { 00224 return SendError; 00225 } 00226 00227 00228 00229 if (!recvBytes(recv, sizeof(recv), 200 * TMOUT)) { 00230 return RecvError; 00231 } 00232 if ((recv[0] == 0x76) 00233 && (recv[1] == 0x00) 00234 && (recv[2] == 0x24) 00235 && (recv[3] == 0x00) 00236 && (recv[4] == 0x00)) { 00237 wait(1); 00238 //return reset(); 00239 switch(br) { 00240 /*case BaudRate9600: 00241 serial.baud(9600); 00242 break;*/ 00243 case BaudRate38400: 00244 serial.baud(38400); 00245 break; 00246 case BaudRate57600: 00247 serial.baud(57600); 00248 break; 00249 case BaudRate115200: 00250 serial.baud(115200); 00251 break; 00252 case BaudRate128000: 00253 serial.baud(128000); 00254 break; 00255 case BaudRate256000: 00256 serial.baud(256000); 00257 break; 00258 default: 00259 return InvalidArguments; 00260 } 00261 return NoError; 00262 } else { 00263 return UnexpectedReply; 00264 } 00265 } 00266 00267 00268 00269 00270 /** 00271 * Take picture. 00272 * 00273 * @return Error code. 00274 */ 00275 Camera_LS_Y201::ErrorCode Camera_LS_Y201::takePicture() 00276 { 00277 uint8_t send[5] = { 00278 0x56, 00279 0x00, 00280 0x36, 00281 0x01, 00282 0x00 00283 }; 00284 uint8_t recv[5]; 00285 00286 if (!sendBytes(send, sizeof(send), 200 * TMOUT)) { 00287 return SendError; 00288 } 00289 if (!recvBytes(recv, sizeof(recv), 2000 * TMOUT)) { 00290 return RecvError; 00291 } 00292 00293 if ((recv[0] == 0x76) 00294 && (recv[1] == 0x00) 00295 && (recv[2] == 0x36) 00296 && (recv[3] == 0x00) 00297 && (recv[4] == 0x00)) { 00298 /* 00299 * I think the camera need a time for operating. 00300 * But there is no any comments on the documents. 00301 */ 00302 wait_ms(100); 00303 return NoError; 00304 } else { 00305 return UnexpectedReply; 00306 } 00307 } 00308 00309 /** 00310 * Read jpeg file size. 00311 * 00312 * @param fileSize File size. 00313 * @return Error code. 00314 */ 00315 Camera_LS_Y201::ErrorCode Camera_LS_Y201::readJpegFileSize(int *fileSize) 00316 { 00317 uint8_t send[5] = { 00318 0x56, 00319 0x00, 00320 0x34, 00321 0x01, 00322 0x00 00323 }; 00324 uint8_t recv[9]; 00325 00326 if (!sendBytes(send, sizeof(send), 2000 * TMOUT)) { 00327 return SendError; 00328 } 00329 if (!recvBytes(recv, sizeof(recv), 2000 * TMOUT)) { 00330 return RecvError; 00331 } 00332 00333 if ((recv[0] == 0x76) 00334 && (recv[1] == 0x00) 00335 && (recv[2] == 0x34) 00336 && (recv[3] == 0x00) 00337 && (recv[4] == 0x04) 00338 && (recv[5] == 0x00) 00339 /*&& (recv[6] == 0x00)*/) { 00340 *fileSize = ((recv[6] & 0x00ff) << 16) 00341 | ((recv[7] & 0x00ff) << 8) 00342 | ((recv[8] & 0x00ff) << 0); 00343 return NoError; 00344 } else { 00345 return UnexpectedReply; 00346 } 00347 } 00348 00349 /** 00350 * Read jpeg file content. 00351 * 00352 * @param func A pointer to a call back function. 00353 * @return Error code. 00354 */ 00355 Camera_LS_Y201::ErrorCode Camera_LS_Y201::readJpegFileContent(void (*func)(int done, int total, uint8_t *buf, size_t siz)) 00356 { 00357 uint8_t send[16] = { 00358 0x56, 00359 0x00, 00360 0x32, 00361 0x0C, 00362 0x00, 00363 0x0A, 00364 0x00, 00365 0x00, // 7 mhh 00366 0x00, // 8 MH 00367 0x00, // 9 ML 00368 0x00, 00369 0x00, // 11 khh 00370 0x00, // 12 KH 00371 0x00, // 13 KL 00372 0x00, // XX 00373 0x00 // XX 00374 }; 00375 uint8_t body[256]; 00376 uint32_t m = 0; // Staring address. 00377 uint32_t k = sizeof(body); // Packet size. 00378 uint16_t x = 10; // Interval time. XX XX * 0.01m[sec] 00379 bool end = false; 00380 00381 /* 00382 * Get the data size. 00383 */ 00384 int siz_done = 0; 00385 int siz_total = 0; 00386 ErrorCode r = readJpegFileSize(&siz_total); 00387 if (r != NoError) { 00388 printf("ouch01\n"); 00389 return r; 00390 } 00391 00392 printf("Going to read %d bytes\n", siz_total); 00393 00394 do { 00395 send[7] = (m >> 16) & 0xff; 00396 send[8] = (m >> 8) & 0xff; 00397 send[9] = (m >> 0) & 0xff; 00398 send[11] = (k >> 16) & 0xff; 00399 send[12] = (k >> 8) & 0xff; 00400 send[13] = (k >> 0) & 0xff; 00401 send[14] = (x >> 8) & 0xff; 00402 send[15] = (x >> 0) & 0xff; 00403 /* 00404 * Send a command. 00405 */ 00406 if (!sendBytes(send, sizeof(send), 200 * TMOUT)) { 00407 printf("ouch02\n"); 00408 return SendError; 00409 } 00410 /* 00411 * Read the header of the response. 00412 */ 00413 uint8_t header[5]; 00414 if (!recvBytes(header, sizeof(header), 2 * 1000 * TMOUT)) { 00415 printf("ouch03\n"); 00416 return RecvError; 00417 } 00418 /* 00419 * Check the response and fetch an image data. 00420 */ 00421 if ((header[0] == 0x76) 00422 && (header[1] == 0x00) 00423 && (header[2] == 0x32) 00424 && (header[3] == 0x00) 00425 && (header[4] == 0x00)) { 00426 if (!recvBytes(body, sizeof(body), 2 * 1000 * TMOUT)) { 00427 printf("ouch04\n"); 00428 return RecvError; 00429 } 00430 siz_done += sizeof(body); 00431 if (func != NULL) { 00432 if (siz_done > siz_total) { 00433 siz_done = siz_total; 00434 } 00435 func(siz_done, siz_total, body, sizeof(body)); 00436 } 00437 for (int i = 1; i < sizeof(body); i++) { 00438 if ((body[i - 1] == 0xFF) && (body[i - 0] == 0xD9)) { 00439 end = true; 00440 } 00441 } 00442 } else { 00443 printf("ouch05\n"); 00444 return UnexpectedReply; 00445 } 00446 /* 00447 * Read the footer of the response. 00448 */ 00449 uint8_t footer[5]; 00450 if (!recvBytes(footer, sizeof(footer), 2 * 1000 * TMOUT)) { 00451 return RecvError; 00452 } 00453 00454 m += sizeof(body); 00455 } while (!end); 00456 return NoError; 00457 } 00458 00459 /** 00460 * Stop taking pictures. 00461 * 00462 * @return Error code. 00463 */ 00464 Camera_LS_Y201::ErrorCode Camera_LS_Y201::stopTakingPictures() 00465 { 00466 uint8_t send[5] = { 00467 0x56, 00468 0x00, 00469 0x36, 00470 0x01, 00471 0x03 00472 }; 00473 uint8_t recv[5]; 00474 00475 if (!sendBytes(send, sizeof(send), 200 * TMOUT)) { 00476 return SendError; 00477 } 00478 if (!recvBytes(recv, sizeof(recv), 200 * TMOUT)) { 00479 return RecvError; 00480 } 00481 00482 if ((recv[0] == 0x76) 00483 && (recv[1] == 0x00) 00484 && (recv[2] == 0x36) 00485 && (recv[3] == 0x00) 00486 && (recv[4] == 0x00)) { 00487 /* 00488 * I think the camera need a time for operating. 00489 * But there is no any comments on the documents. 00490 */ 00491 wait_ms(100); 00492 return NoError; 00493 } else { 00494 return UnexpectedReply; 00495 } 00496 } 00497 00498 /** 00499 * Wait init end codes. 00500 * 00501 * @return True if the data sended. 00502 */ 00503 Camera_LS_Y201::ErrorCode Camera_LS_Y201::waitInitEnd() 00504 { 00505 static const char *PWR_ON_MSG = "Init end\x0d\x0a"; 00506 for (int i = 0; i < strlen(PWR_ON_MSG); i++) { 00507 static const int MAXCNT = 128; 00508 int cnt = 0; 00509 uint8_t c = 0x00; 00510 do { 00511 if (!recvBytes(&c, sizeof(c), 200 * TMOUT)) { 00512 return Timeout; 00513 } 00514 00515 /* 00516 * What is the version of the camera. 00517 * You can check the version with this code. 00518 * 00519 * VC0703 1.00 00520 * 3o ctrl in 00521 * Init end 00522 */ 00523 #if 0 00524 printf("%c", c); 00525 #endif 00526 00527 cnt++; 00528 if (MAXCNT < cnt) { 00529 return UnexpectedReply; 00530 } 00531 } while (c != PWR_ON_MSG[i]); 00532 } 00533 return NoError; 00534 } 00535 00536 /** 00537 * Send bytes to camera module. 00538 * 00539 * @param buf Pointer to the data buffer. 00540 * @param len Length of the data buffer. 00541 * 00542 * @return True if the data sended. 00543 */ 00544 bool Camera_LS_Y201::sendBytes(uint8_t *buf, size_t len, int timeout_us) 00545 { 00546 for (uint32_t i = 0; i < (uint32_t)len; i++) { 00547 int cnt = 0; 00548 while (!serial.writeable()) { 00549 wait_us(1); 00550 cnt++; 00551 if (timeout_us < cnt) { 00552 return false; 00553 } 00554 } 00555 serial.putc(buf[i]); 00556 } 00557 return true; 00558 } 00559 00560 /** 00561 * Receive bytes from camera module. 00562 * 00563 * @param buf Pointer to the data buffer. 00564 * @param len Length of the data buffer. 00565 * 00566 * @return True if the data received. 00567 */ 00568 bool Camera_LS_Y201::recvBytes(uint8_t *buf, size_t len, int timeout_us) 00569 { 00570 for (uint32_t i = 0; i < (uint32_t)len; i++) { 00571 int cnt = 0; 00572 while (!serial.readable()) { 00573 wait_us(1); 00574 cnt++; 00575 if (timeout_us < cnt) { 00576 return false; 00577 } 00578 } 00579 buf[i] = serial.getc(); 00580 } 00581 return true; 00582 } 00583 00584 /** 00585 * Wait received. 00586 * 00587 * @return True if the data received. 00588 */ 00589 bool Camera_LS_Y201::waitRecv() 00590 { 00591 while (!serial.readable()) { 00592 } 00593 return true; 00594 } 00595 00596 /** 00597 * Wait idle state. 00598 */ 00599 bool Camera_LS_Y201::waitIdle() 00600 { 00601 while (serial.readable()) { 00602 serial.getc(); 00603 } 00604 return true; 00605 }
Generated on Wed Jul 13 2022 02:21:16 by 1.7.2