fork of Camera_LS_Y201 lib supporting the 2MP variant/successor

Fork of Camera_LS_Y201 by Shinichiro Nakamura

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Camera_LS_Y201.cpp Source File

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 }