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:
Sun Jun 27 03:36:10 2010 +0000
Child:
1:167e51d598cf
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
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CameraC328.cpp	Sun Jun 27 03:36:10 2010 +0000
@@ -0,0 +1,310 @@
+#include "CameraC328.h"
+
+Serial debout(USBTX, USBRX);
+
+#if 1
+#define SENDFUNC    sendBytesWithDebugOutput
+#define RECVFUNC    recvBytesWithDebugOutput
+#else
+#define SENDFUNC    sendBytes
+#define RECVFUNC    recvBytes
+#endif
+
+CameraC328::CameraC328(PinName tx, PinName rx) : serial(tx, rx) {
+    serial.baud(BAUD);
+}
+
+CameraC328::~CameraC328() {
+}
+
+CameraC328::ErrorNumber CameraC328::sync() {
+    char send[COMMAND_LENGTH];
+    char recv[COMMAND_LENGTH];
+    send[0] = 0xAA;
+    send[1] = 0x0D;
+    send[2] = 0;
+    send[3] = 0;
+    send[4] = 0;
+    send[5] = 0;
+    for (int i = 0; i < SYNCMAX; i++) {
+        if (SENDFUNC(send, sizeof(send))) {
+            if (RECVFUNC(recv, sizeof(recv))) {
+                if ((0xAA == recv[0]) && (0x0E == recv[1])) {
+                    if (RECVFUNC(recv, sizeof(recv))) {
+                        if ((0xAA == recv[0]) && (0x0D == recv[1])) {
+                            send[0] = 0xAA;
+                            send[1] = 0x0E;
+                            send[2] = 0x0D;
+                            send[3] = 0x00;
+                            send[4] = 0x00;
+                            send[5] = 0x00;
+                            if (SENDFUNC(send, sizeof(send))) {
+                                /*
+                                 * After synchronization, the camera needs a little time for AEC and AGC to be stable.
+                                 * Users should wait for 1-2 seconds before capturing the first picture.
+                                 */
+                                wait(1);
+                                return NoError;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        wait(0.2);
+    }
+    return UnexpectedReply;
+}
+
+CameraC328::ErrorNumber CameraC328::getPicture(PictureType pt, void(*func)(size_t done, size_t total, char c)) {
+    switch (pt) {
+        case PreviewPicture:
+            return getPreviewPicture(func);
+        case SnapshotPicture:
+            return getSnapshotPicture(func);
+    }
+    return NoError;
+}
+
+CameraC328::ErrorNumber CameraC328::init(ColorType ct, RawResolution rr, JpegResolution jr) {
+    char send[COMMAND_LENGTH];
+    char recv[COMMAND_LENGTH];
+
+    send[0] = 0xAA;
+    send[1] = 0x01;
+    send[2] = 0x00;
+    send[3] = (char)ct;
+    send[4] = (char)rr;
+    send[5] = (char)jr;
+
+    if (!SENDFUNC(send, sizeof(send))) {
+        return (ErrorNumber)SendRegisterTimeout;
+    }
+
+    if (!RECVFUNC(recv, sizeof(recv))) {
+        return (ErrorNumber)UnexpectedReply;
+    }
+
+    if ((0xAA != recv[0]) || (0x0E != recv[1])) {
+        return (ErrorNumber)recv[4];
+    }
+
+    return (ErrorNumber)NoError;
+}
+
+/*
+ * Get snapshot picture (uncompressed snapshot picture)
+ *
+ * @param func Pointer to a callback function.
+ * @return Status of the error.
+ */
+CameraC328::ErrorNumber CameraC328::getSnapshotPicture(void(*func)(size_t done, size_t total, char c)) {
+
+    char send[COMMAND_LENGTH];
+    char recv[COMMAND_LENGTH];
+
+    send[0] = 0xAA;
+    send[1] = 0x05;
+    send[2] = SnapshotPicture;
+    send[3] = 0x00;
+    send[4] = 0x00;
+    send[5] = 0x00;
+
+    if (!SENDFUNC(send, sizeof(send))) {
+        return (ErrorNumber)SendRegisterTimeout;
+    }
+    if (!RECVFUNC(recv, sizeof(recv))) {
+        return (ErrorNumber)UnexpectedReply;
+    }
+    if ((0xAA != recv[0]) || (0x0E != recv[1])) {
+        return (ErrorNumber)recv[4];
+    }
+
+    send[0] = 0xAA;
+    send[1] = 0x04;
+    send[2] = SnapshotPicture;
+    send[3] = 0x00;
+    send[4] = 0x00;
+    send[5] = 0x00;
+
+    if (!SENDFUNC(send, sizeof(send))) {
+        return (ErrorNumber)SendRegisterTimeout;
+    }
+    wait(1);
+    if (!RECVFUNC(recv, sizeof(recv))) {
+        return (ErrorNumber)UnexpectedReply;
+    }
+    if ((0xAA != recv[0]) || (0x0E != recv[1])) {
+        return (ErrorNumber)recv[4];
+    }
+    wait(1);
+    if (!RECVFUNC(recv, sizeof(recv))) {
+        return (ErrorNumber)UnexpectedReply;
+    }
+    if ((0xAA != recv[0]) || (0x0A != recv[1])) {
+        return (ErrorNumber)UnexpectedReply;
+    }
+
+    size_t siz = (recv[3] << (8 * 2)) | (recv[4] << (8 * 1)) | (recv[5] << (8 * 0));
+    size_t cnt = 0;
+    for (int i = 0; i < (int)siz; i++) {
+        char c;
+        if (!RECVFUNC(&c, sizeof(c))) {
+            return (ErrorNumber)UnexpectedReply;
+        }
+        cnt++;
+        func(cnt, siz, c);
+    }
+
+    return (siz == cnt) ? (ErrorNumber)NoError : (ErrorNumber)SendPictureError;
+}
+
+/*
+ * Get preview picture (uncompressed preview picture)
+ *
+ * @param func Pointer to a callback function.
+ * @return Status of the error.
+ */
+CameraC328::ErrorNumber CameraC328::getPreviewPicture(void(*func)(size_t done, size_t total, char c)) {
+
+    char send[COMMAND_LENGTH];
+    char recv[COMMAND_LENGTH];
+
+    send[0] = 0xAA;
+    send[1] = 0x04;
+    send[2] = PreviewPicture;
+    send[3] = 0x00;
+    send[4] = 0x00;
+    send[5] = 0x00;
+
+    if (!SENDFUNC(send, sizeof(send))) {
+        return (ErrorNumber)SendRegisterTimeout;
+    }
+    wait(1);
+    if (!RECVFUNC(recv, sizeof(recv))) {
+        return (ErrorNumber)UnexpectedReply;
+    }
+    if ((0xAA != recv[0]) || (0x0E != recv[1])) {
+        return (ErrorNumber)recv[4];
+    }
+    wait(1);
+    if (!RECVFUNC(recv, sizeof(recv))) {
+        return (ErrorNumber)UnexpectedReply;
+    }
+    if ((0xAA != recv[0]) || (0x0A != recv[1])) {
+        return (ErrorNumber)UnexpectedReply;
+    }
+
+    size_t siz = (recv[3] << (8 * 2)) | (recv[4] << (8 * 1)) | (recv[5] << (8 * 0));
+    size_t cnt = 0;
+    for (int i = 0; i < (int)siz; i++) {
+        char c;
+        if (!RECVFUNC(&c, sizeof(c))) {
+            return (ErrorNumber)UnexpectedReply;
+        }
+        cnt++;
+        func(cnt, siz, c);
+    }
+
+    return (siz == cnt) ? (ErrorNumber)NoError : (ErrorNumber)SendPictureError;
+}
+
+/**
+ * Send bytes to camera module.
+ *
+ * @param buf Pointer to the data buffer.
+ * @param len Length of the data buffer.
+ *
+ * @return True if the data sended.
+ */
+bool CameraC328::sendBytes(char *buf, size_t len) {
+    for (int i = 0; i < (int)len; i++) {
+        int cnt = 0;
+        while (!serial.writeable()) {
+            wait(0.001);
+            cnt++;
+            if (TIMEOUT_MS < cnt) {
+                return false;
+            }
+        }
+        serial.putc(buf[i]);
+    }
+    return true;
+}
+
+/**
+ * Receive bytes from camera module.
+ *
+ * @param buf Pointer to the data buffer.
+ * @param len Length of the data buffer.
+ *
+ * @return True if the data received.
+ */
+bool CameraC328::recvBytes(char *buf, size_t len) {
+    for (int i = 0; i < (int)len; i++) {
+        int cnt = 0;
+        while (!serial.readable()) {
+            wait(0.001);
+            cnt++;
+            if (TIMEOUT_MS < cnt) {
+                return false;
+            }
+        }
+        buf[i] = serial.getc();
+    }
+    return true;
+}
+
+/**
+ * Send bytes to camera module.
+ *
+ * @param buf Pointer to the data buffer.
+ * @param len Length of the data buffer.
+ *
+ * @return True if the data sended.
+ */
+bool CameraC328::sendBytesWithDebugOutput(char *buf, size_t len) {
+    debout.printf("SEND : ");
+    for (int i = 0; i < (int)len; i++) {
+        int cnt = 0;
+        while (!serial.writeable()) {
+            wait(0.001);
+            cnt++;
+            if (TIMEOUT_MS < cnt) {
+                debout.printf(" [Timed out]\n");
+                return false;
+            }
+        }
+        serial.putc(buf[i]);
+        debout.printf(" %02X", buf[i]);
+    }
+    debout.printf(" [OK]\n");
+    return true;
+}
+
+/**
+ * Receive bytes from camera module.
+ *
+ * @param buf Pointer to the data buffer.
+ * @param len Length of the data buffer.
+ *
+ * @return True if the data received.
+ */
+bool CameraC328::recvBytesWithDebugOutput(char *buf, size_t len) {
+    debout.printf("RECV : ");
+    for (int i = 0; i < (int)len; i++) {
+        int cnt = 0;
+        while (!serial.readable()) {
+            wait(0.001);
+            cnt++;
+            if (TIMEOUT_MS < cnt) {
+                debout.printf(" [Timed out]\n");
+                return false;
+            }
+        }
+        buf[i] = serial.getc();
+        debout.printf(" %02X", buf[i]);
+    }
+    debout.printf(" [OK]\n");
+    return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CameraC328.h	Sun Jun 27 03:36:10 2010 +0000
@@ -0,0 +1,127 @@
+#include "mbed.h"
+
+class CameraC328 {
+public:
+
+    CameraC328(PinName tx, PinName rx);
+
+    ~CameraC328();
+
+    enum ColorType {
+        GrayScale2bit = 0x01,   // 2bit for Y only
+        GrayScale4bit = 0x02,   // 4bit for Y only
+        GrayScale8bit = 0x03,   // 8bit for Y only
+        Color12bit = 0x05,      // 444 (RGB)
+        Color16bit = 0x06,      // 565 (RGB)
+        Jpeg = 0x07
+    };
+
+    enum RawResolution {
+        RawResolution80x60 = 0x01,
+        RawResolution160x120 = 0x03
+    };
+
+    enum JpegResolution {
+        JpegResolution80x64 = 0x01,
+        JpegResolution160x128 = 0x03,
+        JpegResolution320x240 = 0x05,
+        JpegResolution640x480 = 0x07
+    };
+
+    enum ErrorNumber {
+        NoError = 0x00,
+        PictureTypeError = 0x01,
+        PictureUpScale = 0x02,
+        PictureScaleError = 0x03,
+        UnexpectedReply = 0x04,
+        SendPictureTimeout = 0x05,
+        UnexpectedCommand = 0x06,
+        SramJpegTypeError = 0x07,
+        SramJpegSizeError = 0x08,
+        PictureFormatError = 0x09,
+        PictureSizeError = 0x0a,
+        ParameterError = 0x0b,
+        SendRegisterTimeout = 0x0c,
+        CommandIdError = 0x0d,
+        PictureNotReady = 0x0f,
+        TransferPackageNumberError = 0x10,
+        SetTransferPackageSizeWrong = 0x11,
+        CommandHeaderError = 0xf0,
+        CommandLengthError = 0xf1,
+        SendPictureError = 0xf5,
+        SendCommandError = 0xff
+    };
+
+    enum PictureType {
+        SnapshotPicture = 0x01,
+        PreviewPicture = 0x02,
+        JpegPreviewPicture = 0x05
+    };
+
+    ErrorNumber sync();
+    ErrorNumber getPicture(PictureType pt, void(*func)(size_t done, size_t total, char c));
+    ErrorNumber init(ColorType ct, RawResolution rr, JpegResolution jr);
+
+private:
+    Serial serial;
+    static const int COMMAND_LENGTH = 6;
+    static const int TIMEOUT_MS = 200;
+    static const int BAUD = 19600;
+    static const int SYNCMAX = 60;
+
+    /*
+     * Get snapshot picture (uncompressed snapshot picture)
+     *
+     * @param func Pointer to a callback function.
+     * @return Status of the error.
+     */
+    ErrorNumber getSnapshotPicture(void(*func)(size_t done, size_t total, char c));
+
+    /*
+     * Get preview picture (uncompressed preview picture)
+     *
+     * @param func Pointer to a callback function.
+     * @return Status of the error.
+     */
+    ErrorNumber getPreviewPicture(void(*func)(size_t done, size_t total, char c));
+
+    /**
+     * Send bytes to camera module.
+     *
+     * @param buf Pointer to the data buffer.
+     * @param len Length of the data buffer.
+     *
+     * @return True if the data sended.
+     */
+    bool sendBytes(char *buf, size_t len);
+
+    /**
+     * Receive bytes from camera module.
+     *
+     * @param buf Pointer to the data buffer.
+     * @param len Length of the data buffer.
+     *
+     * @return True if the data received.
+     */
+    bool recvBytes(char *buf, size_t len);
+
+    /**
+     * Send bytes to camera module.
+     *
+     * @param buf Pointer to the data buffer.
+     * @param len Length of the data buffer.
+     *
+     * @return True if the data sended.
+     */
+    bool sendBytesWithDebugOutput(char *buf, size_t len);
+
+    /**
+     * Receive bytes from camera module.
+     *
+     * @param buf Pointer to the data buffer.
+     * @param len Length of the data buffer.
+     *
+     * @return True if the data received.
+     */
+    bool recvBytesWithDebugOutput(char *buf, size_t len);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Jun 27 03:36:10 2010 +0000
@@ -0,0 +1,53 @@
+#include "mbed.h"
+#include "CameraC328.h"
+
+DigitalOut myled1(LED1);
+DigitalOut myled2(LED2);
+CameraC328 camera(p9, p10);
+Serial serial(USBTX, USBRX);
+
+void cbfunc(size_t done, size_t total, char c) {
+    serial.printf("%8d/%8d\r", done, total);
+}
+
+int main() {
+    serial.baud(19200);
+    serial.printf("\n");
+    serial.printf("==========\n");
+    serial.printf("CameraC328\n");
+    serial.printf("==========\n");
+    CameraC328::ErrorNumber err = CameraC328::NoError;
+
+    err = camera.sync();
+    if (CameraC328::NoError == err) {
+        serial.printf("[ OK ] : CameraC328::sync\n");
+    } else {
+        serial.printf("[FAIL] : CameraC328::sync (Error=%d)\n", (int)err);
+    }
+
+    err = camera.init(CameraC328::Jpeg, CameraC328::RawResolution160x120, CameraC328::JpegResolution640x480);
+    if (CameraC328::NoError == err) {
+        serial.printf("[ OK ] : CameraC328::init\n");
+    } else {
+        serial.printf("[FAIL] : CameraC328::init (Error=%d)\n", (int)err);
+    }
+
+    // err = camera.getPicture(CameraC328::SnapshotPicture, cbfunc);
+    err = camera.getPicture(CameraC328::PreviewPicture, cbfunc);
+    if (CameraC328::NoError == err) {
+        serial.printf("[ OK ] : CameraC328::getPicture\n");
+    } else {
+        serial.printf("[FAIL] : CameraC328::getPicture (Error=%d)\n", (int)err);
+    }
+
+    while (1) {
+        myled1 = 1;
+        wait(0.2);
+        myled1 = 0;
+        wait(0.2);
+        myled2 = 1;
+        wait(0.2);
+        myled2 = 0;
+        wait(0.2);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Jun 27 03:36:10 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/3944f1e2fa4f