CameraC328

Dependents:   CameraC328_TestProgram CameraC328_Thresholding Camera_TestProgram_2015 Camera_TestProgram_2015 ... more

Files at this revision

API Documentation at this revision

Comitter:
shintamainjp
Date:
Tue Jun 29 22:55:35 2010 +0000
Parent:
3:6d3150d4396a
Child:
5:5d2088c2433c
Commit message:

Changed in this revision

CameraC328.cpp Show annotated file Show diff for this revision Revisions of this file
CameraC328.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/CameraC328.cpp	Tue Jun 29 11:45:53 2010 +0000
+++ b/CameraC328.cpp	Tue Jun 29 22:55:35 2010 +0000
@@ -1,11 +1,8 @@
 /**
- * C328-7640 device driver class
+ * C328-7640 device driver class (Version 0.0.2)
  * Reference documents: C328-7640 User Manual v3.0 2004.8.19
  *
- * Version 0.0.1
- *
  * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
- * shinta.main.jp@gmail.com
  * http://shinta.main.jp/
  */
 
@@ -15,6 +12,8 @@
 #define RECVFUNC    recvBytes
 #define WAITFUNC    waitRecv
 
+Serial debout(USBTX, USBRX);
+
 CameraC328::CameraC328(PinName tx, PinName rx, Baud baud) : serial(tx, rx) {
     serial.baud((int)baud);
 }
@@ -56,11 +55,25 @@
         return en;
     }
 
+    static bool alreadySetupPackageSize = false;
+    if (!alreadySetupPackageSize) {
+        en = sendSetPackageSize(packageSize);
+        if (NoError != en) {
+            return en;
+        }
+        WAITFUNC();
+        en = recvAckOrNck();
+        if (NoError != en) {
+            return en;
+        }
+        alreadySetupPackageSize = true;
+    }
+
     return (ErrorNumber)NoError;
 }
 
 /**
- * Get uncompressed snapshot picture (uncompressed snapshot picture)
+ * Get uncompressed snapshot picture.
  *
  * @param func Pointer to a callback function.
  * @return Status of the error.
@@ -121,7 +134,7 @@
 }
 
 /**
- * Get uncompressed snapshot picture (uncompressed snapshot picture)
+ * Get uncompressed preview picture.
  *
  * @param func Pointer to a callback function.
  * @return Status of the error.
@@ -171,6 +184,198 @@
     return (ErrorNumber)NoError;
 }
 
+/**
+ * Get JPEG snapshot picture.
+ *
+ * @param func Pointer to a callback function.
+ * @return Status of the error.
+ */
+CameraC328::ErrorNumber CameraC328::getJpegSnapshotPicture(void(*func)(char *buf, size_t siz)) {
+
+    ErrorNumber en;
+
+    en = sendSnapshot(CompressedPicture, 1);
+    if (NoError != en) {
+        return en;
+    }
+    WAITFUNC();
+    en = recvAckOrNck();
+    if (NoError != en) {
+        return en;
+    }
+
+    en = sendGetPicture(SnapshotPicture);
+    if (NoError != en) {
+        return en;
+    }
+    WAITFUNC();
+    en = recvAckOrNck();
+    if (NoError != en) {
+        return en;
+    }
+
+    /*
+     * Data : snapshot picture
+     */
+    DataType dt;
+    uint32_t length = 0;
+    WAITFUNC();
+    en = recvData(&dt, &length);
+    if (NoError != en) {
+        return en;
+    }
+    en = sendAck(0x00, 0);
+    if (NoError != en) {
+        return en;
+    }
+
+    WAITFUNC();
+
+    char databuf[packageSize - 6];
+    uint16_t pkg_total = length / (packageSize - 6);
+    for (int i = 0; i <= (int)pkg_total; i++) {
+        uint16_t checksum = 0;
+        // ID.
+        char idbuf[2];
+        if (!RECVFUNC(idbuf, sizeof(idbuf))) {
+            return (ErrorNumber)UnexpectedReply;
+        }
+        checksum += idbuf[0];
+        checksum += idbuf[1];
+        uint16_t id = (idbuf[1] << 8) | (idbuf[0] << 0);
+        if (id != i) {
+            return (ErrorNumber)UnexpectedReply;
+        }
+
+        // Size of the data.
+        char dsbuf[2];
+        if (!RECVFUNC(dsbuf, sizeof(dsbuf))) {
+            return (ErrorNumber)UnexpectedReply;
+        }
+
+        // Received the data.
+        checksum += dsbuf[0];
+        checksum += dsbuf[1];
+        uint16_t ds = (dsbuf[1] << 8) | (dsbuf[0] << 0);
+        if (!RECVFUNC(&databuf[0], ds)) {
+            return (ErrorNumber)UnexpectedReply;
+        }
+        for (int j = 0; j < ds; j++) {
+            checksum += databuf[j];
+        }
+
+        // Verify code.
+        char vcbuf[2];
+        if (!RECVFUNC(vcbuf, sizeof(vcbuf))) {
+            return (ErrorNumber)UnexpectedReply;
+        }
+        uint16_t vc = (vcbuf[1] << 8) | (vcbuf[0] << 0);
+        if (vc != (checksum & 0xff)) {
+            return (ErrorNumber)UnexpectedReply;
+        }
+
+        func(databuf, ds);
+
+        en = sendAck(0x00, 1 + i);
+        if (NoError != en) {
+            return en;
+        }
+    }
+
+    return (ErrorNumber)NoError;
+}
+
+/**
+ * Get JPEG preview picture.
+ *
+ * @param func Pointer to a callback function.
+ * @return Status of the error.
+ */
+CameraC328::ErrorNumber CameraC328::getJpegPreviewPicture(void(*func)(char *buf, size_t siz)) {
+
+    ErrorNumber en;
+
+    en = sendGetPicture(JpegPreviewPicture);
+    if (NoError != en) {
+        return en;
+    }
+    WAITFUNC();
+    en = recvAckOrNck();
+    if (NoError != en) {
+        return en;
+    }
+
+    /*
+     * Data : JPEG preview picture
+     */
+    DataType dt;
+    uint32_t length = 0;
+    WAITFUNC();
+    en = recvData(&dt, &length);
+    if (NoError != en) {
+        return en;
+    }
+    en = sendAck(0x00, 0);
+    if (NoError != en) {
+        return en;
+    }
+
+    WAITFUNC();
+
+    char databuf[packageSize - 6];
+    uint16_t pkg_total = length / (packageSize - 6);
+    for (int i = 0; i <= (int)pkg_total; i++) {
+        uint16_t checksum = 0;
+        // ID.
+        char idbuf[2];
+        if (!RECVFUNC(idbuf, sizeof(idbuf))) {
+            return (ErrorNumber)UnexpectedReply;
+        }
+        checksum += idbuf[0];
+        checksum += idbuf[1];
+        uint16_t id = (idbuf[1] << 8) | (idbuf[0] << 0);
+        if (id != i) {
+            return (ErrorNumber)UnexpectedReply;
+        }
+
+        // Size of the data.
+        char dsbuf[2];
+        if (!RECVFUNC(dsbuf, sizeof(dsbuf))) {
+            return (ErrorNumber)UnexpectedReply;
+        }
+
+        // Received the data.
+        checksum += dsbuf[0];
+        checksum += dsbuf[1];
+        uint16_t ds = (dsbuf[1] << 8) | (dsbuf[0] << 0);
+        if (!RECVFUNC(&databuf[0], ds)) {
+            return (ErrorNumber)UnexpectedReply;
+        }
+        for (int j = 0; j < ds; j++) {
+            checksum += databuf[j];
+        }
+
+        // Verify code.
+        char vcbuf[2];
+        if (!RECVFUNC(vcbuf, sizeof(vcbuf))) {
+            return (ErrorNumber)UnexpectedReply;
+        }
+        uint16_t vc = (vcbuf[1] << 8) | (vcbuf[0] << 0);
+        if (vc != (checksum & 0xff)) {
+            return (ErrorNumber)UnexpectedReply;
+        }
+
+        func(databuf, ds);
+
+        en = sendAck(0x00, 1 + i);
+        if (NoError != en) {
+            return en;
+        }
+    }
+
+    return (ErrorNumber)NoError;
+}
+
 CameraC328::ErrorNumber CameraC328::sendInitial(ColorType ct, RawResolution rr, JpegResolution jr) {
     char send[COMMAND_LENGTH];
 
--- a/CameraC328.h	Tue Jun 29 11:45:53 2010 +0000
+++ b/CameraC328.h	Tue Jun 29 22:55:35 2010 +0000
@@ -1,16 +1,16 @@
 /**
- * C328-7640 device driver class
+ * C328-7640 device driver class (Version 0.0.2)
  * Reference documents: C328-7640 User Manual v3.0 2004.8.19
  *
- * Version 0.0.1
- *
  * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
- * shinta.main.jp@gmail.com
  * http://shinta.main.jp/
  */
 
 #include "mbed.h"
 
+#ifndef _CAMERA_C328_H_
+#define _CAMERA_C328_H_
+
 class CameraC328 {
 public:
 
@@ -100,11 +100,14 @@
     ErrorNumber init(ColorType ct, RawResolution rr, JpegResolution jr);
     ErrorNumber getUncompressedSnapshotPicture(void(*func)(size_t done, size_t total, char c));
     ErrorNumber getUncompressedPreviewPicture(void(*func)(size_t done, size_t total, char c));
+    ErrorNumber getJpegSnapshotPicture(void(*func)(char *buf, size_t siz));
+    ErrorNumber getJpegPreviewPicture(void(*func)(char *buf, size_t siz));
 
 private:
     Serial serial;
     static const int COMMAND_LENGTH = 6;
     static const int SYNCMAX = 60;
+    static const int packageSize = 512;
 
     ErrorNumber sendInitial(ColorType ct, RawResolution rr, JpegResolution jr);
     ErrorNumber sendGetPicture(PictureType pt);
@@ -119,7 +122,9 @@
     ErrorNumber sendAck(uint8_t commandId, uint16_t packageId);
     ErrorNumber recvAckOrNck();
 
-    bool sendBytes(char *buf, size_t len, int timeout_us = 5000);
-    bool recvBytes(char *buf, size_t len, int timeout_us = 5000);
+    bool sendBytes(char *buf, size_t len, int timeout_us = 20000);
+    bool recvBytes(char *buf, size_t len, int timeout_us = 20000);
     bool waitRecv();
 };
+
+#endif
--- a/main.cpp	Tue Jun 29 11:45:53 2010 +0000
+++ b/main.cpp	Tue Jun 29 22:55:35 2010 +0000
@@ -1,11 +1,8 @@
 /**
- * C328-7640 device driver test program
+ * C328-7640 device driver class (Version 0.0.2)
  * Reference documents: C328-7640 User Manual v3.0 2004.8.19
  *
- * Version 0.0.1
- *
  * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
- * shinta.main.jp@gmail.com
  * http://shinta.main.jp/
  */
 
@@ -20,11 +17,18 @@
 const int IMG_X = 80;
 const int IMG_Y = 60;
 char buf[IMG_X * IMG_Y * 2];
+FILE *fp_jpeg;
 
-void cbfunc(size_t done, size_t total, char c) {
+void uncompressed_callback(size_t done, size_t total, char c) {
     buf[done - 1] = c;
 }
 
+void jpeg_callback(char *buf, size_t siz) {
+    for (int i = 0; i < (int)siz; i++) {
+        fprintf(fp_jpeg, "%c", buf[i]); 
+    }
+}
+
 void sync(void) {
     CameraC328::ErrorNumber err = CameraC328::NoError;
 
@@ -47,7 +51,7 @@
     }
 
     for (int i = 0; i < 10; i++) {
-        err = camera.getUncompressedSnapshotPicture(cbfunc);
+        err = camera.getUncompressedSnapshotPicture(uncompressed_callback);
         if (CameraC328::NoError == err) {
             serial.printf("[ OK ] : CameraC328::getUncompressedSnapshotPicture\n");
         } else {
@@ -85,7 +89,7 @@
     }
 
     for (int i = 0; i < 10; i++) {
-        err = camera.getUncompressedPreviewPicture(cbfunc);
+        err = camera.getUncompressedPreviewPicture(uncompressed_callback);
         if (CameraC328::NoError == err) {
             serial.printf("[ OK ] : CameraC328::getUncompressedPreviewPicture\n");
         } else {
@@ -112,6 +116,58 @@
     }
 }
 
+void test_jpeg_snapshot_picture(void) {
+    CameraC328::ErrorNumber err = CameraC328::NoError;
+
+    err = camera.init(CameraC328::Jpeg, CameraC328::RawResolution80x60, CameraC328::JpegResolution640x480);
+    if (CameraC328::NoError == err) {
+        serial.printf("[ OK ] : CameraC328::init\n");
+    } else {
+        serial.printf("[FAIL] : CameraC328::init (Error=%02X)\n", (int)err);
+    }
+        
+    for (int i = 0; i < 10; i++) {
+        char fname[64];
+        snprintf(fname, sizeof(fname), "/fs/jpss%04d.jpg", i);
+        fp_jpeg = fopen(fname, "w");
+        
+        err = camera.getJpegSnapshotPicture(jpeg_callback);
+        if (CameraC328::NoError == err) {
+            serial.printf("[ OK ] : CameraC328::getJpegSnapshotPicture\n");
+        } else {
+            serial.printf("[FAIL] : CameraC328::getJpegSnapshotPicture (Error=%02X)\n", (int)err);
+        }
+
+        fclose(fp_jpeg);
+    }
+}
+
+void test_jpeg_preview_picture(void) {
+    CameraC328::ErrorNumber err = CameraC328::NoError;
+
+    err = camera.init(CameraC328::Jpeg, CameraC328::RawResolution80x60, CameraC328::JpegResolution640x480);
+    if (CameraC328::NoError == err) {
+        serial.printf("[ OK ] : CameraC328::init\n");
+    } else {
+        serial.printf("[FAIL] : CameraC328::init (Error=%02X)\n", (int)err);
+    }
+        
+    for (int i = 0; i < 10; i++) {
+        char fname[64];
+        snprintf(fname, sizeof(fname), "/fs/jppv%04d.jpg", i);
+        fp_jpeg = fopen(fname, "w");
+
+        err = camera.getJpegPreviewPicture(jpeg_callback);
+        if (CameraC328::NoError == err) {
+            serial.printf("[ OK ] : CameraC328::getJpegPreviewPicture\n");
+        } else {
+            serial.printf("[FAIL] : CameraC328::getJpegPreviewPicture (Error=%02X)\n", (int)err);
+        }
+
+        fclose(fp_jpeg);
+    }
+}
+
 int main() {
     serial.baud(19200);
     serial.printf("\n");
@@ -120,8 +176,12 @@
     serial.printf("==========\n");
     
     sync();
+    #if 0
     test_uncompressed_snapshot_picture();
     test_uncompressed_preview_picture();
+    #endif
+    test_jpeg_preview_picture();
+    test_jpeg_snapshot_picture();
 
     while (1) {
         myled1 = 1;