Eric Williams / Mbed 2 deprecated Lab3_Surveillance

Dependencies:   GPS mbed

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