fork of Camera_LS_Y201 lib supporting the 2MP variant/successor

Fork of Camera_LS_Y201 by Shinichiro Nakamura

Files at this revision

API Documentation at this revision

Comitter:
humlet
Date:
Tue Mar 18 17:28:47 2014 +0000
Parent:
1:43358d40f879
Commit message:
Got it running for the crappy LS-Y201-2MP; quickNdirty

Changed in this revision

Camera_LS_Y201.cpp Show annotated file Show diff for this revision Revisions of this file
Camera_LS_Y201.h Show annotated file Show diff for this revision Revisions of this file
diff -r 43358d40f879 -r ce4d1351bdeb Camera_LS_Y201.cpp
--- a/Camera_LS_Y201.cpp	Wed Dec 01 23:10:56 2010 +0000
+++ b/Camera_LS_Y201.cpp	Tue Mar 18 17:28:47 2014 +0000
@@ -28,20 +28,24 @@
 
 #include "Camera_LS_Y201.h"
 
+#define TMOUT 2000
+
 /**
  * Create.
  *
  * @param tx Transmitter.
  * @param rx Receiver.
  */
-Camera_LS_Y201::Camera_LS_Y201(PinName tx, PinName rx) : serial(tx, rx) {
-    serial.baud(38400);
+Camera_LS_Y201::Camera_LS_Y201(PinName tx, PinName rx) : serial(tx, rx)
+{
+    serial.baud(115200);
 }
 
 /**
  * Dispose.
  */
-Camera_LS_Y201::~Camera_LS_Y201() {
+Camera_LS_Y201::~Camera_LS_Y201()
+{
 }
 
 /**
@@ -49,20 +53,44 @@
  *
  * @return Error code.
  */
-Camera_LS_Y201::ErrorCode Camera_LS_Y201::reset() {
+Camera_LS_Y201::ErrorCode Camera_LS_Y201::reset()
+{
     uint8_t send[4] = {
         0x56,
         0x00,
         0x26,
         0x00
     };
-    uint8_t recv[4];
+    //uint8_t recv[50];
 
-    waitIdle();
-    if (!sendBytes(send, sizeof(send), 200 * 1000)) {
-        return SendError;
+    const int nBauds = 5;
+    const int bauds[nBauds] = {38400,57600,115200,128000,256000};
+    for(int i=0; i<nBauds; ++i) {
+        printf("Reset @ %d baud: ",bauds[i]);
+        serial.baud(bauds[i]);
+        waitIdle();
+        if (!sendBytes(send, sizeof(send), 200 * TMOUT)) {
+            printf("TxKO\n");
+            continue;
+        } else {
+            printf("TxOK ");
+        }
+        
+        //serial.baud(115200);
+        
+        ErrorCode r = waitInitEnd();
+        if (r != NoError) {
+            printf("RxKO\n");
+            continue;
+        } else {
+            printf("RxOK ...4s...\n");
+            wait(4);
+            return NoError;
+        }
     }
-    if (!recvBytes(recv, sizeof(recv), 200 * 1000)) {
+    return UnexpectedReply;
+    /*
+    if (!recvBytes(recv, sizeof(recv), 200 * TMOUT)) {
         return RecvError;
     }
     if ((recv[0] == 0x76)
@@ -76,8 +104,10 @@
         wait(4);
         return NoError;
     } else {
+        printf("%X %X %X %X\n",recv[0],recv[1],recv[2],recv[3]);
         return UnexpectedReply;
     }
+    */
 }
 
 /**
@@ -86,36 +116,83 @@
  * @param is Image size.
  * @return Error code.
  */
-Camera_LS_Y201::ErrorCode Camera_LS_Y201::setImageSize(ImageSize is) {
-    uint8_t send[9] = {
+Camera_LS_Y201::ErrorCode Camera_LS_Y201::setImageSize(ImageSize is)
+{
+    uint8_t send[5] = {
         0x56,
         0x00,
-        0x31,
-        0x05,
-        0x04,
+        0x54,
         0x01,
-        0x00,
-        0x19,
         0x00    // 0x11:320x240, 0x00:640x480, 0x22:160x120
     };
     uint8_t recv[5];
     switch (is) {
         case ImageSize160x120:
-            send[8] = 0x22;
+            send[4] = 0x22;
             break;
-        case ImageSize320x280:
-            send[8] = 0x11;
+        case ImageSize320x240:
+            send[4] = 0x11;
             break;
         case ImageSize640x480:
-            send[8] = 0x00;
+            send[4] = 0x00;
+            break;
+        case ImageSize800x600:
+            send[4] = 0x1d;
+            break;
+        case ImageSize1024x768:
+            send[4] = 0x1c;
+            break;
+        case ImageSize1280x960:
+            send[4] = 0x1b;
+            break;
+        case ImageSize1600x1200:
+            send[4] = 0x21;
             break;
         default:
             return InvalidArguments;
     }
-    if (!sendBytes(send, sizeof(send), 200 * 1000)) {
+    if (!sendBytes(send, sizeof(send), 200 * TMOUT)) {
         return SendError;
     }
-    if (!recvBytes(recv, sizeof(recv), 200 * 1000)) {
+    if (!recvBytes(recv, sizeof(recv), 200 * TMOUT)) {
+        return RecvError;
+    }
+    if ((recv[0] == 0x76)
+            && (recv[1] == 0x00)
+            && (recv[2] == 0x54)
+            && (recv[3] == 0x00)
+            && (recv[4] == 0x00)) {
+        wait(1);
+        //return reset();
+        return NoError;
+    } else {
+        return UnexpectedReply;
+    }
+}
+
+
+
+Camera_LS_Y201::ErrorCode Camera_LS_Y201::setCompressionRatio(int cr)
+{
+    uint8_t send[9] = {
+        0x56,
+        0x00,
+        0x31,
+        0x05,
+        0x01,
+        0x01,
+        0x12,
+        0x04,
+        cr
+    };
+    uint8_t recv[5];
+
+    //printf("Setting Img-Qual to %d\n", cr);
+
+    if (!sendBytes(send, sizeof(send), 200 * TMOUT)) {
+        return SendError;
+    }
+    if (!recvBytes(recv, sizeof(recv), 200 * TMOUT)) {
         return RecvError;
     }
     if ((recv[0] == 0x76)
@@ -124,18 +201,79 @@
             && (recv[3] == 0x00)
             && (recv[4] == 0x00)) {
         wait(1);
-        return reset();
+        //return reset();
+        return NoError;
     } else {
         return UnexpectedReply;
     }
 }
 
+Camera_LS_Y201::ErrorCode Camera_LS_Y201::setBaudRate(Camera_LS_Y201::BaudRate br)
+{
+    uint8_t send[6] = {
+        0x56,
+        0x00,
+        0x24,
+        0x03,
+        0x01,
+        br
+    };
+    uint8_t recv[5];
+
+    if (!sendBytes(send, sizeof(send), 200 * TMOUT)) {
+        return SendError;
+    }
+
+
+
+    if (!recvBytes(recv, sizeof(recv), 200 * TMOUT)) {
+        return RecvError;
+    }
+    if ((recv[0] == 0x76)
+            && (recv[1] == 0x00)
+            && (recv[2] == 0x24)
+            && (recv[3] == 0x00)
+            && (recv[4] == 0x00)) {
+        wait(1);
+        //return reset();
+        switch(br) {
+                /*case BaudRate9600:
+                    serial.baud(9600);
+                    break;*/
+            case BaudRate38400:
+                serial.baud(38400);
+                break;
+            case BaudRate57600:
+                serial.baud(57600);
+                break;
+            case BaudRate115200:
+                serial.baud(115200);
+                break;
+            case BaudRate128000:
+                serial.baud(128000);
+                break;
+            case BaudRate256000:
+                serial.baud(256000);
+                break;
+            default:
+                return InvalidArguments;
+        }
+        return NoError;
+    } else {
+        return UnexpectedReply;
+    }
+}
+
+
+
+
 /**
  * Take picture.
  *
  * @return Error code.
  */
-Camera_LS_Y201::ErrorCode Camera_LS_Y201::takePicture() {
+Camera_LS_Y201::ErrorCode Camera_LS_Y201::takePicture()
+{
     uint8_t send[5] = {
         0x56,
         0x00,
@@ -145,10 +283,10 @@
     };
     uint8_t recv[5];
 
-    if (!sendBytes(send, sizeof(send), 200 * 1000)) {
+    if (!sendBytes(send, sizeof(send), 200 * TMOUT)) {
         return SendError;
     }
-    if (!recvBytes(recv, sizeof(recv), 200 * 1000)) {
+    if (!recvBytes(recv, sizeof(recv), 2000 * TMOUT)) {
         return RecvError;
     }
 
@@ -174,7 +312,8 @@
  * @param fileSize File size.
  * @return Error code.
  */
-Camera_LS_Y201::ErrorCode Camera_LS_Y201::readJpegFileSize(int *fileSize) {
+Camera_LS_Y201::ErrorCode Camera_LS_Y201::readJpegFileSize(int *fileSize)
+{
     uint8_t send[5] = {
         0x56,
         0x00,
@@ -184,10 +323,10 @@
     };
     uint8_t recv[9];
 
-    if (!sendBytes(send, sizeof(send), 200 * 1000)) {
+    if (!sendBytes(send, sizeof(send), 2000 * TMOUT)) {
         return SendError;
     }
-    if (!recvBytes(recv, sizeof(recv), 200 * 1000)) {
+    if (!recvBytes(recv, sizeof(recv), 2000 * TMOUT)) {
         return RecvError;
     }
 
@@ -197,9 +336,10 @@
             && (recv[3] == 0x00)
             && (recv[4] == 0x04)
             && (recv[5] == 0x00)
-            && (recv[6] == 0x00)) {
-        *fileSize = ((recv[7] & 0x00ff) << 8)
-                    | ((recv[8] & 0x00ff) << 0);
+            /*&& (recv[6] == 0x00)*/) {
+        *fileSize =     ((recv[6] & 0x00ff) << 16)
+                        |   ((recv[7] & 0x00ff) << 8)
+                        |   ((recv[8] & 0x00ff) << 0);
         return NoError;
     } else {
         return UnexpectedReply;
@@ -212,7 +352,8 @@
  * @param func A pointer to a call back function.
  * @return Error code.
  */
-Camera_LS_Y201::ErrorCode Camera_LS_Y201::readJpegFileContent(void (*func)(int done, int total, uint8_t *buf, size_t siz)) {
+Camera_LS_Y201::ErrorCode Camera_LS_Y201::readJpegFileContent(void (*func)(int done, int total, uint8_t *buf, size_t siz))
+{
     uint8_t send[16] = {
         0x56,
         0x00,
@@ -221,19 +362,19 @@
         0x00,
         0x0A,
         0x00,
-        0x00,
-        0x00, // MH
-        0x00, // ML
+        0x00, // 7 mhh
+        0x00, // 8 MH
+        0x00, // 9 ML
         0x00,
-        0x00,
-        0x00, // KH
-        0x00, // KL
+        0x00, // 11 khh
+        0x00, // 12 KH
+        0x00, // 13 KL
         0x00, // XX
         0x00  // XX
     };
-    uint8_t body[32];
-    uint16_t m = 0; // Staring address.
-    uint16_t k = sizeof(body); // Packet size.
+    uint8_t body[256];
+    uint32_t m = 0; // Staring address.
+    uint32_t k = sizeof(body); // Packet size.
     uint16_t x = 10;    // Interval time. XX XX * 0.01m[sec]
     bool end = false;
 
@@ -244,12 +385,17 @@
     int siz_total = 0;
     ErrorCode r = readJpegFileSize(&siz_total);
     if (r != NoError) {
+        printf("ouch01\n");
         return r;
     }
 
+    printf("Going to read %d bytes\n", siz_total);
+
     do {
+        send[7] = (m >> 16) & 0xff;
         send[8] = (m >> 8) & 0xff;
         send[9] = (m >> 0) & 0xff;
+        send[11] = (k >> 16) & 0xff;
         send[12] = (k >> 8) & 0xff;
         send[13] = (k >> 0) & 0xff;
         send[14] = (x >> 8) & 0xff;
@@ -257,14 +403,16 @@
         /*
          * Send a command.
          */
-        if (!sendBytes(send, sizeof(send), 200 * 1000)) {
+        if (!sendBytes(send, sizeof(send), 200 * TMOUT)) {
+            printf("ouch02\n");
             return SendError;
         }
         /*
          * Read the header of the response.
          */
         uint8_t header[5];
-        if (!recvBytes(header, sizeof(header), 2 * 1000 * 1000)) {
+        if (!recvBytes(header, sizeof(header), 2 * 1000 * TMOUT)) {
+            printf("ouch03\n");
             return RecvError;
         }
         /*
@@ -275,7 +423,8 @@
                 && (header[2] == 0x32)
                 && (header[3] == 0x00)
                 && (header[4] == 0x00)) {
-            if (!recvBytes(body, sizeof(body), 2 * 1000 * 1000)) {
+            if (!recvBytes(body, sizeof(body), 2 * 1000 * TMOUT)) {
+                printf("ouch04\n");
                 return RecvError;
             }
             siz_done += sizeof(body);
@@ -291,13 +440,14 @@
                 }
             }
         } else {
+            printf("ouch05\n");
             return UnexpectedReply;
         }
         /*
          * Read the footer of the response.
          */
         uint8_t footer[5];
-        if (!recvBytes(footer, sizeof(footer), 2 * 1000 * 1000)) {
+        if (!recvBytes(footer, sizeof(footer), 2 * 1000 * TMOUT)) {
             return RecvError;
         }
 
@@ -311,7 +461,8 @@
  *
  * @return Error code.
  */
-Camera_LS_Y201::ErrorCode Camera_LS_Y201::stopTakingPictures() {
+Camera_LS_Y201::ErrorCode Camera_LS_Y201::stopTakingPictures()
+{
     uint8_t send[5] = {
         0x56,
         0x00,
@@ -321,10 +472,10 @@
     };
     uint8_t recv[5];
 
-    if (!sendBytes(send, sizeof(send), 200 * 1000)) {
+    if (!sendBytes(send, sizeof(send), 200 * TMOUT)) {
         return SendError;
     }
-    if (!recvBytes(recv, sizeof(recv), 200 * 1000)) {
+    if (!recvBytes(recv, sizeof(recv), 200 * TMOUT)) {
         return RecvError;
     }
 
@@ -349,14 +500,15 @@
  *
  * @return True if the data sended.
  */
-Camera_LS_Y201::ErrorCode Camera_LS_Y201::waitInitEnd() {
+Camera_LS_Y201::ErrorCode Camera_LS_Y201::waitInitEnd()
+{
     static const char *PWR_ON_MSG = "Init end\x0d\x0a";
     for (int i = 0; i < strlen(PWR_ON_MSG); i++) {
         static const int MAXCNT = 128;
         int cnt = 0;
         uint8_t c = 0x00;
         do {
-            if (!recvBytes(&c, sizeof(c), 500 * 1000)) {
+            if (!recvBytes(&c, sizeof(c), 200 * TMOUT)) {
                 return Timeout;
             }
 
@@ -389,7 +541,8 @@
  *
  * @return True if the data sended.
  */
-bool Camera_LS_Y201::sendBytes(uint8_t *buf, size_t len, int timeout_us) {
+bool Camera_LS_Y201::sendBytes(uint8_t *buf, size_t len, int timeout_us)
+{
     for (uint32_t i = 0; i < (uint32_t)len; i++) {
         int cnt = 0;
         while (!serial.writeable()) {
@@ -412,7 +565,8 @@
  *
  * @return True if the data received.
  */
-bool Camera_LS_Y201::recvBytes(uint8_t *buf, size_t len, int timeout_us) {
+bool Camera_LS_Y201::recvBytes(uint8_t *buf, size_t len, int timeout_us)
+{
     for (uint32_t i = 0; i < (uint32_t)len; i++) {
         int cnt = 0;
         while (!serial.readable()) {
@@ -432,7 +586,8 @@
  *
  * @return True if the data received.
  */
-bool Camera_LS_Y201::waitRecv() {
+bool Camera_LS_Y201::waitRecv()
+{
     while (!serial.readable()) {
     }
     return true;
@@ -441,7 +596,8 @@
 /**
  * Wait idle state.
  */
-bool Camera_LS_Y201::waitIdle() {
+bool Camera_LS_Y201::waitIdle()
+{
     while (serial.readable()) {
         serial.getc();
     }
diff -r 43358d40f879 -r ce4d1351bdeb Camera_LS_Y201.h
--- a/Camera_LS_Y201.h	Wed Dec 01 23:10:56 2010 +0000
+++ b/Camera_LS_Y201.h	Tue Mar 18 17:28:47 2014 +0000
@@ -67,11 +67,25 @@
      * Image size.
      */
     enum ImageSize {
-        ImageSize160x120,   /**< 160x120. */
-        ImageSize320x280,   /**< 320x280. */
-        ImageSize640x480    /**< 640x480. */
+        ImageSize160x120, // crappy ... firmware seems to record the upper left part of the image   
+        ImageSize320x240, // OK 
+        ImageSize640x480, // OK  
+        ImageSize800x600,   
+        ImageSize1024x768,  
+        ImageSize1280x960,  
+        ImageSize1600x1200 // OK
     };
 
+    enum BaudRate {
+        //BaudRate9600=0xae,   // doesn't seem to work, not investiated, as no one seriously will use 9600 baud anyway
+        BaudRate38400=0x2a,   
+        BaudRate57600=0x1c,   
+        BaudRate115200=0x0d,   
+        BaudRate128000=0x7e,    
+        BaudRate256000=0x56
+    };
+
+    
     /**
      * Reset module.
      *
@@ -87,6 +101,13 @@
      */
     ErrorCode setImageSize(ImageSize is);
 
+
+    // values: 0..9 highest compression at 9 
+    // Ups, and value 5 is simply ignored by the firmware
+    ErrorCode setCompressionRatio(int cr);
+    
+    ErrorCode setBaudRate(BaudRate br);
+
     /**
      * Take picture.
      *