CANSAT_CAMERA

Dependents:   CANSAT_COMBINED CANSAT_CAMERA_servo CANSAT_CAMERA2

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 /**
00032  * Create.
00033  *
00034  * @param tx Transmitter.
00035  * @param rx Receiver.
00036  */
00037 Camera_LS_Y201::Camera_LS_Y201(PinName tx, PinName rx) : serial(tx, rx) {
00038     serial.baud(38400);
00039 }
00040 Camera_LS_Y201::ErrorCode Camera_LS_Y201::baud()
00041 {
00042     
00043 uint8_t send[7] = {
00044         0x56,
00045         0x00,
00046         0x24,
00047         0x03,
00048         0x01,
00049         0x0D,
00050         0xA6
00051 //        56 00 24 03 01 XX XX
00052     };
00053 uint8_t recv[5];
00054 waitIdle();
00055 sendBytes(send, sizeof(send), 200 * 1000) ;
00056     
00057     
00058 recvBytes(recv, sizeof(recv), 200 * 1000) ;
00059     serial.baud(115200);
00060     }
00061 
00062 /**
00063  * Dispose.
00064  */
00065 Camera_LS_Y201::~Camera_LS_Y201() {
00066 }
00067 
00068 /**
00069  * Reset module.
00070  *
00071  * @return Error code.
00072  */
00073 Camera_LS_Y201::ErrorCode Camera_LS_Y201::reset() {
00074     uint8_t send[4] = {
00075         0x56,
00076         0x00,
00077         0x26,
00078         0x00
00079     };
00080     uint8_t recv[4];
00081 
00082     waitIdle();
00083     if (!sendBytes(send, sizeof(send), 200 * 1000)) {
00084         return SendError;
00085     }
00086     if (!recvBytes(recv, sizeof(recv), 200 * 1000)) {
00087         return RecvError;
00088     }
00089     for(int i=0;i<4;i++)
00090     {
00091         printf("%x\n\r",recv[i]);
00092         }
00093     if ((recv[0] == 0x76)
00094             && (recv[1] == 0x00)
00095             && (recv[2] == 0x26)
00096             && (recv[3] == 0x00)) {
00097         ErrorCode r = waitInitEnd();
00098         if (r != NoError) {
00099             return r;
00100         }
00101         wait(4);
00102         return NoError;
00103     } else {
00104         return UnexpectedReply;
00105     }
00106 }
00107 
00108 /**
00109  * Set image size.
00110  *
00111  * @param is Image size.
00112  * @return Error code.
00113  */
00114 Camera_LS_Y201::ErrorCode Camera_LS_Y201::setImageSize(ImageSize is) {
00115     uint8_t send[9] = {
00116         0x56,
00117         0x00,
00118         0x31,
00119         0x05,
00120         0x04,
00121         0x01,
00122         0x00,
00123         0x19,
00124         0x00    // 0x11:320x240, 0x00:640x480, 0x22:160x120
00125     };
00126     uint8_t recv[5];
00127     switch (is) {
00128         case ImageSize160x120:
00129             send[8] = 0x22;
00130             break;
00131         case ImageSize320x280:
00132             send[8] = 0x11;
00133             break;
00134         case ImageSize640x480:
00135             send[8] = 0x00;
00136             break;
00137         default:
00138             return InvalidArguments;
00139     }
00140     if (!sendBytes(send, sizeof(send), 200 * 1000)) {
00141         return SendError;
00142     }
00143     if (!recvBytes(recv, sizeof(recv), 200 * 1000)) {
00144         return RecvError;
00145     }
00146     if ((recv[0] == 0x76)
00147             && (recv[1] == 0x00)
00148             && (recv[2] == 0x31)
00149             && (recv[3] == 0x00)
00150             && (recv[4] == 0x00)) {
00151         wait(1);
00152         return reset();
00153     } else {
00154         return UnexpectedReply;
00155     }
00156 }
00157 
00158 /**
00159  * Take picture.
00160  *
00161  * @return Error code.
00162  */
00163 Camera_LS_Y201::ErrorCode Camera_LS_Y201::takePicture() {
00164     uint8_t send[5] = {
00165         0x56,
00166         0x00,
00167         0x36,
00168         0x01,
00169         0x00
00170     };
00171     uint8_t recv[5];
00172 
00173     if (!sendBytes(send, sizeof(send), 200 * 1000)) {
00174         return SendError;
00175     }
00176     if (!recvBytes(recv, sizeof(recv), 200 * 1000)) {
00177         return RecvError;
00178     }
00179 
00180     if ((recv[0] == 0x76)
00181             && (recv[1] == 0x00)
00182             && (recv[2] == 0x36)
00183             && (recv[3] == 0x00)
00184             && (recv[4] == 0x00)) {
00185         /*
00186          * I think the camera need a time for operating.
00187          * But there is no any comments on the documents.
00188          */
00189         wait_ms(100);
00190         return NoError;
00191     } else {
00192         return UnexpectedReply;
00193     }
00194 }
00195 
00196 /**
00197  * Read jpeg file size.
00198  *
00199  * @param fileSize File size.
00200  * @return Error code.
00201  */
00202 Camera_LS_Y201::ErrorCode Camera_LS_Y201::readJpegFileSize(int *fileSize) {
00203     uint8_t send[5] = {
00204         0x56,
00205         0x00,
00206         0x34,
00207         0x01,
00208         0x00
00209     };
00210     uint8_t recv[9];
00211 
00212     if (!sendBytes(send, sizeof(send), 200 * 1000)) {
00213         return SendError;
00214     }
00215     if (!recvBytes(recv, sizeof(recv), 200 * 1000)) {
00216         return RecvError;
00217     }
00218 
00219     if ((recv[0] == 0x76)
00220             && (recv[1] == 0x00)
00221             && (recv[2] == 0x34)
00222             && (recv[3] == 0x00)
00223             && (recv[4] == 0x04)
00224             && (recv[5] == 0x00)
00225             && (recv[6] == 0x00)) {
00226         *fileSize = ((recv[7] & 0x00ff) << 8)
00227                     | ((recv[8] & 0x00ff) << 0);
00228         return NoError;
00229     } else {
00230         return UnexpectedReply;
00231     }
00232 }
00233 
00234 /**
00235  * Read jpeg file content.
00236  *
00237  * @param func A pointer to a call back function.
00238  * @return Error code.
00239  */
00240 Camera_LS_Y201::ErrorCode Camera_LS_Y201::readJpegFileContent(void (*func)(int done, int total, uint8_t *buf, size_t siz)) {
00241     uint8_t send[16] = {
00242         0x56,
00243         0x00,
00244         0x32,
00245         0x0C,
00246         0x00,
00247         0x0A,
00248         0x00,
00249         0x00,
00250         0x00, // MH
00251         0x00, // ML
00252         0x00,
00253         0x00,
00254         0x00, // KH
00255         0x00, // KL
00256         0x00, // XX
00257         0x00  // XX
00258     };
00259     uint8_t body[32];
00260     uint16_t m = 0; // Staring address.
00261     uint16_t k = sizeof(body); // Packet size.
00262     uint16_t x = 10;    // Interval time. XX XX * 0.01m[sec]
00263     bool end = false;
00264 
00265     /*
00266      * Get the data size.
00267      */
00268     int siz_done = 0;
00269     int siz_total = 0;
00270     ErrorCode r = readJpegFileSize(&siz_total);
00271     if (r != NoError) {
00272         return r;
00273     }
00274 
00275     do {
00276         send[8] = (m >> 8) & 0xff;
00277         send[9] = (m >> 0) & 0xff;
00278         send[12] = (k >> 8) & 0xff;
00279         send[13] = (k >> 0) & 0xff;
00280         send[14] = (x >> 8) & 0xff;
00281         send[15] = (x >> 0) & 0xff;
00282         /*
00283          * Send a command.
00284          */
00285         if (!sendBytes(send, sizeof(send), 200 * 1000)) {
00286             return SendError;
00287         }
00288         /*
00289          * Read the header of the response.
00290          */
00291         uint8_t header[5];
00292         if (!recvBytes(header, sizeof(header), 2 * 1000 * 1000)) {
00293             return RecvError;
00294         }
00295         /*
00296          * Check the response and fetch an image data.
00297          */
00298         if ((header[0] == 0x76)
00299                 && (header[1] == 0x00)
00300                 && (header[2] == 0x32)
00301                 && (header[3] == 0x00)
00302                 && (header[4] == 0x00)) {
00303             if (!recvBytes(body, sizeof(body), 2 * 1000 * 1000)) {
00304                 return RecvError;
00305             }
00306             //printf("saved");
00307             siz_done += sizeof(body);
00308             if (func != NULL) {
00309                 if (siz_done > siz_total) {
00310                     siz_done = siz_total;
00311                 }
00312                 func(siz_done, siz_total, body, sizeof(body));
00313             }
00314             for (int i = 1; i < sizeof(body); i++) {
00315                 if ((body[i - 1] == 0xFF) && (body[i - 0] == 0xD9)) {
00316                     end = true;
00317                 }
00318             }
00319         } else {
00320             return UnexpectedReply;
00321         }
00322         /*
00323          * Read the footer of the response.
00324          */
00325         uint8_t footer[5];
00326         if (!recvBytes(footer, sizeof(footer), 2 * 1000 * 1000)) {
00327             return RecvError;
00328         }
00329 
00330         m += sizeof(body);
00331     } while (!end);
00332     return NoError;
00333 }
00334 
00335 /**
00336  * Stop taking pictures.
00337  *
00338  * @return Error code.
00339  */
00340 Camera_LS_Y201::ErrorCode Camera_LS_Y201::stopTakingPictures() {
00341     uint8_t send[5] = {
00342         0x56,
00343         0x00,
00344         0x36,
00345         0x01,
00346         0x03
00347     };
00348     uint8_t recv[5];
00349 
00350     if (!sendBytes(send, sizeof(send), 200 * 1000)) {
00351         return SendError;
00352     }
00353     if (!recvBytes(recv, sizeof(recv), 200 * 1000)) {
00354         return RecvError;
00355     }
00356 
00357     if ((recv[0] == 0x76)
00358             && (recv[1] == 0x00)
00359             && (recv[2] == 0x36)
00360             && (recv[3] == 0x00)
00361             && (recv[4] == 0x00)) {
00362         /*
00363          * I think the camera need a time for operating.
00364          * But there is no any comments on the documents.
00365          */
00366         wait_ms(100);
00367         return NoError;
00368     } else {
00369         return UnexpectedReply;
00370     }
00371 }
00372 
00373 /**
00374  * Wait init end codes.
00375  *
00376  * @return True if the data sended.
00377  */
00378 Camera_LS_Y201::ErrorCode Camera_LS_Y201::waitInitEnd() {
00379     static const char *PWR_ON_MSG = "Init end\x0d\x0a";
00380     for (int i = 0; i < strlen(PWR_ON_MSG); i++) {
00381         static const int MAXCNT = 128;
00382         int cnt = 0;
00383         uint8_t c = 0x00;
00384         do {
00385             if (!recvBytes(&c, sizeof(c), 500 * 1000)) {
00386                 return Timeout;
00387             }
00388 
00389             /*
00390              * What is the version of the camera.
00391              * You can check the version with this code.
00392              *
00393              * VC0703 1.00
00394              * 3o ctrl in
00395              * Init end
00396              */
00397 #if 0
00398             printf("%c", c);
00399 #endif
00400 
00401             cnt++;
00402             if (MAXCNT < cnt) {
00403                 return UnexpectedReply;
00404             }
00405         } while (c != PWR_ON_MSG[i]);
00406     }
00407     return NoError;
00408 }
00409 
00410 /**
00411  * Send bytes to camera module.
00412  *
00413  * @param buf Pointer to the data buffer.
00414  * @param len Length of the data buffer.
00415  *
00416  * @return True if the data sended.
00417  */
00418 bool Camera_LS_Y201::sendBytes(uint8_t *buf, size_t len, int timeout_us) {
00419     for (uint32_t i = 0; i < (uint32_t)len; i++) {
00420         int cnt = 0;
00421         while (!serial.writeable()) {
00422             wait_us(1);
00423             cnt++;
00424             if (timeout_us < cnt) {
00425                 return false;
00426             }
00427         }
00428         serial.putc(buf[i]);
00429     }
00430     return true;
00431 }
00432 
00433 /**
00434  * Receive bytes from camera module.
00435  *
00436  * @param buf Pointer to the data buffer.
00437  * @param len Length of the data buffer.
00438  *
00439  * @return True if the data received.
00440  */
00441 bool Camera_LS_Y201::recvBytes(uint8_t *buf, size_t len, int timeout_us) {
00442     for (uint32_t i = 0; i < (uint32_t)len; i++) {
00443         int cnt = 0;
00444         while (!serial.readable()) {
00445             wait_us(1);
00446             cnt++;
00447             if (timeout_us < cnt) {
00448                 return false;
00449             }
00450         }
00451         buf[i] = serial.getc();
00452     }
00453     return true;
00454 }
00455 
00456 /**
00457  * Wait received.
00458  *
00459  * @return True if the data received.
00460  */
00461 bool Camera_LS_Y201::waitRecv() {
00462     while (!serial.readable()) {
00463     }
00464     return true;
00465 }
00466 
00467 /**
00468  * Wait idle state.
00469  */
00470 bool Camera_LS_Y201::waitIdle() {
00471     while (serial.readable()) {
00472         serial.getc();
00473     }
00474     return true;
00475 }