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 11:45:53 2010 +0000
Parent:
2:6a72fcad5c0a
Child:
4:ad06342d4b84
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	Mon Jun 28 13:57:15 2010 +0000
+++ b/CameraC328.cpp	Tue Jun 29 11:45:53 2010 +0000
@@ -1,65 +1,178 @@
+/**
+ * C328-7640 device driver class
+ * 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 "CameraC328.h"
 
-Serial debout(USBTX, USBRX);
-
-#if 0
-#define SENDFUNC    sendBytesWithDebugOutput
-#define RECVFUNC    recvBytesWithDebugOutput
-#else
 #define SENDFUNC    sendBytes
 #define RECVFUNC    recvBytes
-#endif
+#define WAITFUNC    waitRecv
 
-CameraC328::CameraC328(PinName tx, PinName rx) : serial(tx, rx), syncdone(false) {
-    serial.baud(BAUD);
+CameraC328::CameraC328(PinName tx, PinName rx, Baud baud) : serial(tx, rx) {
+    serial.baud((int)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))) {
-                                syncdone = true;
-                                /*
-                                 * 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;
-                            }
-                        }
+        if (NoError == sendSync()) {
+            if (NoError == recvAckOrNck()) {
+                if (NoError == recvSync()) {
+                    if (NoError == sendAck(0x0D, 0x00)) {
+                        /*
+                         * 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(2);
+                        return NoError;
                     }
                 }
             }
         }
-        wait(0.200);
+        wait_ms(50);
     }
     return UnexpectedReply;
 }
 
 CameraC328::ErrorNumber CameraC328::init(ColorType ct, RawResolution rr, JpegResolution jr) {
+    ErrorNumber en;
+
+    en = sendInitial(ct, rr, jr);
+    if (NoError != en) {
+        return en;
+    }
+    WAITFUNC();
+    en = recvAckOrNck();
+    if (NoError != en) {
+        return en;
+    }
+
+    return (ErrorNumber)NoError;
+}
+
+/**
+ * Get uncompressed snapshot picture (uncompressed snapshot picture)
+ *
+ * @param func Pointer to a callback function.
+ * @return Status of the error.
+ */
+CameraC328::ErrorNumber CameraC328::getUncompressedSnapshotPicture(void(*func)(size_t done, size_t total, char c)) {
+    ErrorNumber en;
+
+    en = sendSnapshot(UncompressedPicture, 0);
+    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;
+    }
+
+    /*
+     * image data
+     */
+    DataType dt;
+    uint32_t length = 0;
+    WAITFUNC();
+    en = recvData(&dt, &length);
+    if (NoError != en) {
+        return en;
+    }
+    size_t imgcnt = 0;
+    for (int i = 0; i < (int)length; i++) {
+        char c;
+        WAITFUNC();
+        if (!RECVFUNC(&c, 1)) {
+            return (ErrorNumber)UnexpectedReply;
+        }
+        imgcnt++;
+        func(imgcnt, length, c);
+    }
+
+    /*
+     * ACK
+     */
+    en = sendAck(0x0A, 0x00);
+    if (NoError != en) {
+        return en;
+    }
+
+    return (ErrorNumber)NoError;
+}
+
+/**
+ * Get uncompressed snapshot picture (uncompressed snapshot picture)
+ *
+ * @param func Pointer to a callback function.
+ * @return Status of the error.
+ */
+CameraC328::ErrorNumber CameraC328::getUncompressedPreviewPicture(void(*func)(size_t done, size_t total, char c)) {
+    ErrorNumber en;
+
+    en = sendGetPicture(PreviewPicture);
+    if (NoError != en) {
+        return en;
+    }
+    WAITFUNC();
+    en = recvAckOrNck();
+    if (NoError != en) {
+        return en;
+    }
+
+    /*
+     * image data
+     */
+    DataType dt;
+    uint32_t length = 0;
+    WAITFUNC();
+    en = recvData(&dt, &length);
+    if (NoError != en) {
+        return en;
+    }
+    size_t imgcnt = 0;
+    for (int i = 0; i < (int)length; i++) {
+        char c;
+        WAITFUNC();
+        if (!RECVFUNC(&c, 1)) {
+            return (ErrorNumber)UnexpectedReply;
+        }
+        imgcnt++;
+        func(imgcnt, length, c);
+    }
+
+    /*
+     * ACK
+     */
+    en = sendAck(0x0A, 0x00);
+    if (NoError != en) {
+        return en;
+    }
+
+    return (ErrorNumber)NoError;
+}
+
+CameraC328::ErrorNumber CameraC328::sendInitial(ColorType ct, RawResolution rr, JpegResolution jr) {
     char send[COMMAND_LENGTH];
-    char recv[COMMAND_LENGTH];
 
     send[0] = 0xAA;
     send[1] = 0x01;
@@ -71,36 +184,15 @@
     if (!SENDFUNC(send, sizeof(send))) {
         return (ErrorNumber)SendRegisterTimeout;
     }
-
-    wait(0.2);
-    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::getJpegSnapshotPicture(void(*func)(size_t done, size_t total, char c)) {
-
+CameraC328::ErrorNumber CameraC328::sendGetPicture(PictureType pt) {
     char send[COMMAND_LENGTH];
-    char recv[COMMAND_LENGTH];
 
-    /*
-     * Snapshot (uncompressed picture)
-     */
     send[0] = 0xAA;
-    send[1] = 0x05;
-    send[2] = (char)UncompressedPicture;
+    send[1] = 0x04;
+    send[2] = (char)pt;
     send[3] = 0x00;
     send[4] = 0x00;
     send[5] = 0x00;
@@ -108,20 +200,105 @@
     if (!SENDFUNC(send, sizeof(send))) {
         return (ErrorNumber)SendRegisterTimeout;
     }
-    if (!RECVFUNC(recv, sizeof(recv))) {
-        return (ErrorNumber)UnexpectedReply;
+    return (ErrorNumber)NoError;
+}
+
+CameraC328::ErrorNumber CameraC328::sendSnapshot(SnapshotType st, uint16_t skipFrames) {
+    char send[COMMAND_LENGTH];
+    send[0] = 0xAA;
+    send[1] = 0x05;
+    send[2] = (char)st;
+    send[3] = (skipFrames >> 0) & 0xff;
+    send[4] = (skipFrames >> 8) & 0xff;
+    send[5] = 0x00;
+
+    if (!SENDFUNC(send, sizeof(send))) {
+        return (ErrorNumber)SendRegisterTimeout;
+    }
+    return (ErrorNumber)NoError;
+}
+
+CameraC328::ErrorNumber CameraC328::sendSetPackageSize(uint16_t packageSize) {
+    char send[COMMAND_LENGTH];
+    send[0] = 0xAA;
+    send[1] = 0x06;
+    send[2] = 0x08;
+    send[3] = (packageSize >> 0) & 0xff;
+    send[4] = (packageSize >> 8) & 0xff;
+    send[5] = 0x00;
+
+    if (!SENDFUNC(send, sizeof(send))) {
+        return (ErrorNumber)SendRegisterTimeout;
     }
-    if ((0xAA != recv[0]) || (0x0E != recv[1])) {
-        return (ErrorNumber)recv[4];
+    return (ErrorNumber)NoError;
+}
+
+CameraC328::ErrorNumber CameraC328::sendSetBaudrate(Baud baud) {
+    char send[COMMAND_LENGTH];
+
+    static struct baud_list {
+        Baud baud;
+        uint8_t div1st;
+        uint8_t div2nd;
+    } baudtable [] = {
+        { Baud7200, 0xff, 0x01 },
+        { Baud9600, 0xbf, 0x01 },
+        { Baud14400, 0x7f, 0x01 },
+        { Baud19200, 0x5f, 0x01 },
+        { Baud28800, 0x3f, 0x01 },
+        { Baud38400, 0x2f, 0x01 },
+        { Baud57600, 0x1f, 0x01 },
+        { Baud115200, 0x0f, 0x01 }
+    };
+
+    uint8_t div1st = 0x00, div2nd = 0x00;
+    struct baud_list *p = &baudtable[0];
+    for (int i = 0; i < sizeof(baudtable) / sizeof(baudtable[0]); i++) {
+        if (p->baud == baud) {
+            div1st = p->div1st;
+            div2nd = p->div2nd;
+        }
+        p++;
     }
 
+    send[0] = 0xAA;
+    send[1] = 0x07;
+    send[2] = div1st;
+    send[3] = div2nd;
+    send[4] = 0x00;
+    send[5] = 0x00;
+
+    if (!SENDFUNC(send, sizeof(send))) {
+        return (ErrorNumber)SendRegisterTimeout;
+    }
+
+    return (ErrorNumber)NoError;
+}
+
+CameraC328::ErrorNumber CameraC328::sendReset(ResetType rt, bool specialReset) {
+    char send[COMMAND_LENGTH];
+    send[0] = 0xAA;
+    send[1] = 0x08;
+    send[2] = (int)rt;
+    send[3] = 0x00;
+    send[4] = 0x00;
+    send[5] = specialReset ? 0xff : 0x00;
     /*
-     * Get picture (snapshot picture)
+     * Special reset : If the parameter is 0xFF, the command is a special Reset command and the firmware responds to it immediately.
      */
 
+    if (!SENDFUNC(send, sizeof(send))) {
+        return (ErrorNumber)SendRegisterTimeout;
+    }
+
+    return (ErrorNumber)NoError;
+}
+
+CameraC328::ErrorNumber CameraC328::sendPowerOff() {
+    char send[COMMAND_LENGTH];
     send[0] = 0xAA;
-    send[1] = 0x04;
-    send[2] = (char)SnapshotPicture;
+    send[1] = 0x09;
+    send[2] = 0x00;
     send[3] = 0x00;
     send[4] = 0x00;
     send[5] = 0x00;
@@ -129,52 +306,88 @@
     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];
-    }
 
-    /*
-     * image data
-     */
-    while (!serial.readable()) {
-    }
+    return (ErrorNumber)NoError;
+}
+
+CameraC328::ErrorNumber CameraC328::recvData(DataType *dt, uint32_t *length) {
+    char recv[COMMAND_LENGTH];
     if (!RECVFUNC(recv, sizeof(recv))) {
         return (ErrorNumber)UnexpectedReply;
     }
     if ((0xAA != recv[0]) || (0x0A != recv[1])) {
-        return (ErrorNumber)recv[4];
+        return (ErrorNumber)UnexpectedReply;
     }
-    size_t imgsiz = (recv[5] << 16) | (recv[4] << 8) | (recv[3] << 0);
-    size_t imgcnt = 0;
-    for (int i = 0; i < (int)imgsiz; i++) {
-        char c;
-        if (!RECVFUNC(&c, 1)) {
-            return (ErrorNumber)UnexpectedReply;
-        }
-        imgcnt++;
-        func(imgcnt, imgsiz, c);
-    }
+    *dt = (DataType)recv[2];
+    *length = (recv[5] << 16) | (recv[4] << 8) | (recv[3] << 0);
+    return (ErrorNumber)NoError;
+}
 
-    /*
-     * ACK
-     */
+CameraC328::ErrorNumber CameraC328::sendSync() {
+    char send[COMMAND_LENGTH];
     send[0] = 0xAA;
-    send[1] = 0x0E;
-    send[2] = 0x0A;
+    send[1] = 0x0D;
+    send[2] = 0x00;
     send[3] = 0x00;
     send[4] = 0x00;
     send[5] = 0x00;
     if (!SENDFUNC(send, sizeof(send))) {
         return (ErrorNumber)SendRegisterTimeout;
     }
+    return (ErrorNumber)NoError;
+}
 
+CameraC328::ErrorNumber CameraC328::recvSync() {
+    char recv[COMMAND_LENGTH];
+    if (!RECVFUNC(recv, sizeof(recv))) {
+        return (ErrorNumber)UnexpectedReply;
+    }
+    if ((0xAA != recv[0]) || (0x0D != recv[1])) {
+        return (ErrorNumber)UnexpectedReply;
+    }
     return (ErrorNumber)NoError;
 }
 
 /**
+ * Send ACK.
+ *
+ * @param commandId The command with that ID is acknowledged by this command.
+ * @param packageId For acknowledging Data command, these two bytes represent the requested package ID. While for acknowledging other commands, these two bytes are set to 00h.
+ */
+CameraC328::ErrorNumber CameraC328::sendAck(uint8_t commandId, uint16_t packageId) {
+    char send[COMMAND_LENGTH];
+    send[0] = 0xAA;
+    send[1] = 0x0E;
+    send[2] = commandId;
+    send[3] = 0x00;    // ACK counter is not used.
+    send[4] = (packageId >> 0) & 0xff;
+    send[5] = (packageId >> 8) & 0xff;
+    if (!SENDFUNC(send, sizeof(send))) {
+        return (ErrorNumber)SendRegisterTimeout;
+    }
+    return (ErrorNumber)NoError;
+}
+
+/**
+ * Receive ACK or NCK.
+ *
+ * @return Error number.
+ */
+CameraC328::ErrorNumber CameraC328::recvAckOrNck() {
+    char recv[COMMAND_LENGTH];
+    if (!RECVFUNC(recv, sizeof(recv))) {
+        return (ErrorNumber)UnexpectedReply;
+    }
+    if ((0xAA == recv[0]) && (0x0E == recv[1])) {
+        return (ErrorNumber)NoError;
+    }
+    if ((0xAA == recv[0]) && (0x0F == recv[1])) {
+        return (ErrorNumber)recv[4];
+    }
+    return (ErrorNumber)UnexpectedReply;
+}
+
+/**
  * Send bytes to camera module.
  *
  * @param buf Pointer to the data buffer.
@@ -182,13 +395,13 @@
  *
  * @return True if the data sended.
  */
-bool CameraC328::sendBytes(char *buf, size_t len) {
+bool CameraC328::sendBytes(char *buf, size_t len, int timeout_us) {
     for (uint32_t i = 0; i < (uint32_t)len; i++) {
         int cnt = 0;
         while (!serial.writeable()) {
-            wait(0.000001);
+            wait_us(1);
             cnt++;
-            if (TIMEOUT_US < cnt) {
+            if (timeout_us < cnt) {
                 return false;
             }
         }
@@ -198,56 +411,6 @@
 }
 
 /**
- * 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 (uint32_t i = 0; i < (uint32_t)len; i++) {
-        int cnt = 0;
-        while (!serial.writeable()) {
-            wait(0.000001);
-            cnt++;
-            if (TIMEOUT_US < 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::recvBytes(char *buf, size_t len) {
-    for (uint32_t i = 0; i < (uint32_t)len; i++) {
-        int cnt = 0;
-        while (!serial.readable()) {
-            wait(0.000001);
-            cnt++;
-            if (TIMEOUT_US < cnt) {
-                return false;
-            }
-        }
-        buf[i] = serial.getc();
-    }
-    return true;
-}
-
-/**
  * Receive bytes from camera module.
  *
  * @param buf Pointer to the data buffer.
@@ -255,21 +418,28 @@
  *
  * @return True if the data received.
  */
-bool CameraC328::recvBytesWithDebugOutput(char *buf, size_t len) {
-    debout.printf("RECV : ");
+bool CameraC328::recvBytes(char *buf, size_t len, int timeout_us) {
     for (uint32_t i = 0; i < (uint32_t)len; i++) {
         int cnt = 0;
         while (!serial.readable()) {
-            wait(0.000001);
+            wait_us(1);
             cnt++;
-            if (TIMEOUT_US < cnt) {
-                debout.printf(" [Timed out]\n");
+            if (timeout_us < cnt) {
                 return false;
             }
         }
         buf[i] = serial.getc();
-        debout.printf(" %02X", buf[i]);
     }
-    debout.printf(" [OK]\n");
     return true;
 }
+
+/**
+ * Wait received.
+ *
+ * @return True if the data received.
+ */
+bool CameraC328::waitRecv() {
+    while (!serial.readable()) {
+    }
+    return true;
+}
\ No newline at end of file
--- a/CameraC328.h	Mon Jun 28 13:57:15 2010 +0000
+++ b/CameraC328.h	Tue Jun 29 11:45:53 2010 +0000
@@ -1,12 +1,19 @@
+/**
+ * C328-7640 device driver class
+ * 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"
 
 class CameraC328 {
 public:
 
-    CameraC328(PinName tx, PinName rx);
-
-    ~CameraC328();
-
     enum ColorType {
         GrayScale2bit = 0x01,   // 2bit for Y only
         GrayScale4bit = 0x02,   // 4bit for Y only
@@ -51,11 +58,6 @@
         SendPictureError = 0xf5,
         SendCommandError = 0xff
     };
-    
-    enum SnapshotType {
-        CompressedPicture = 0x00,
-        UncompressedPicture = 0x01
-    };
 
     enum PictureType {
         SnapshotPicture = 0x01,
@@ -63,55 +65,61 @@
         JpegPreviewPicture = 0x05
     };
 
+    enum SnapshotType {
+        CompressedPicture = 0x00,
+        UncompressedPicture = 0x01
+    };
+
+    enum Baud {
+        Baud7200 = 7200,
+        Baud9600 = 9600,
+        Baud14400 = 14400,
+        Baud19200 = 19200,  // Default.
+        Baud28800 = 28800,
+        Baud38400 = 38400,
+        Baud57600 = 57600,
+        Baud115200 = 115200
+    };
+
+    enum ResetType {
+        ResetWholeSystem = 0x00,
+        ResetStateMachines = 0x01
+    };
+
+    enum DataType {
+        DataTypeSnapshotPicture = 0x01,
+        DataTypePreviewPicture = 0x02,
+        DataTypeJpegPreviewPicture = 0x05
+    };
+
+    CameraC328(PinName tx, PinName rx, Baud baud = Baud19200);
+
+    ~CameraC328();
+
     ErrorNumber sync();
     ErrorNumber init(ColorType ct, RawResolution rr, JpegResolution jr);
-    ErrorNumber getJpegSnapshotPicture(void(*func)(size_t done, size_t total, char c));
+    ErrorNumber getUncompressedSnapshotPicture(void(*func)(size_t done, size_t total, char c));
+    ErrorNumber getUncompressedPreviewPicture(void(*func)(size_t done, size_t total, char c));
 
 private:
     Serial serial;
-    bool syncdone;
     static const int COMMAND_LENGTH = 6;
-    static const int TIMEOUT_US = 1200;
-    static const int BAUD = 57600;
     static const int SYNCMAX = 60;
 
-    /**
-     * 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);
+    ErrorNumber sendInitial(ColorType ct, RawResolution rr, JpegResolution jr);
+    ErrorNumber sendGetPicture(PictureType pt);
+    ErrorNumber sendSnapshot(SnapshotType st, uint16_t skipFrames);
+    ErrorNumber sendSetPackageSize(uint16_t packageSize);
+    ErrorNumber sendSetBaudrate(Baud baud);
+    ErrorNumber sendReset(ResetType rt, bool specialReset);
+    ErrorNumber sendPowerOff();
+    ErrorNumber recvData(DataType *dt, uint32_t *length);
+    ErrorNumber sendSync();
+    ErrorNumber recvSync();
+    ErrorNumber sendAck(uint8_t commandId, uint16_t packageId);
+    ErrorNumber recvAckOrNck();
 
-    /**
-     * 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);
+    bool sendBytes(char *buf, size_t len, int timeout_us = 5000);
+    bool recvBytes(char *buf, size_t len, int timeout_us = 5000);
+    bool waitRecv();
 };
--- a/main.cpp	Mon Jun 28 13:57:15 2010 +0000
+++ b/main.cpp	Tue Jun 29 11:45:53 2010 +0000
@@ -1,72 +1,136 @@
-#include "mbed.h"
-#include "CameraC328.h"
-
-DigitalOut myled1(LED1);
-DigitalOut myled2(LED2);
-CameraC328 camera(p9, p10);
-Serial serial(USBTX, USBRX);
-LocalFileSystem fs ("fs");
-const int IMG_X = 80;
-const int IMG_Y = 60;
-char buf[IMG_X * IMG_Y * 2];
-
-void cbfunc(size_t done, size_t total, char c) {
-    buf[done - 1] = c;
-}
-
-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=%02X)\n", (int)err);
-    }
-
-    err = camera.init(CameraC328::Color16bit, CameraC328::RawResolution80x60, CameraC328::JpegResolution80x64);
-    if (CameraC328::NoError == err) {
-        serial.printf("[ OK ] : CameraC328::init\n");
-    } else {
-        serial.printf("[FAIL] : CameraC328::init (Error=%02X)\n", (int)err);
-    }
-
-    err = camera.getJpegSnapshotPicture(cbfunc);
-    if (CameraC328::NoError == err) {
-        serial.printf("[ OK ] : CameraC328::getPicture(PreviewPicture)\n");
-    } else {
-        serial.printf("[FAIL] : CameraC328::getPicture(PreviewPicture) (Error=%02X)\n", (int)err);
-    }
-
-    FILE *fp = fopen("/fs/img.ppm","w");
-    fprintf(fp, "P3\n");
-    fprintf(fp, "%d %d\n", IMG_X, IMG_Y);
-    fprintf(fp, "%d\n", 255);
-    for (int y = 0; y < IMG_Y; y++) {
-        for (int x = 0; x < IMG_X; x++) {
-            int adrofs = y * (IMG_X * 2) + (x * 2);
-            uint16_t dat = (buf[adrofs + 0] << 8) | (buf[adrofs + 1] << 0);
-            uint8_t r = ((dat >> 11) & 0x1f) << 3;
-            uint8_t g = ((dat >> 5) & 0x3f) << 2;
-            uint8_t b = ((dat >> 0) & 0x1f) << 3;
-            fprintf(fp,"%d %d %d\n", r, g, b);
-        }
-    }
-    fclose(fp);
-
-    while (1) {
-        myled1 = 1;
-        wait(0.2);
-        myled1 = 0;
-        wait(0.2);
-        myled2 = 1;
-        wait(0.2);
-        myled2 = 0;
-        wait(0.2);
-    }
-}
+/**
+ * C328-7640 device driver test program
+ * 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"
+#include "CameraC328.h"
+
+DigitalOut myled1(LED1);
+DigitalOut myled2(LED2);
+CameraC328 camera(p9, p10, CameraC328::Baud57600);
+Serial serial(USBTX, USBRX);
+LocalFileSystem fs ("fs");
+const int IMG_X = 80;
+const int IMG_Y = 60;
+char buf[IMG_X * IMG_Y * 2];
+
+void cbfunc(size_t done, size_t total, char c) {
+    buf[done - 1] = c;
+}
+
+void sync(void) {
+    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=%02X)\n", (int)err);
+    }
+}
+
+void test_uncompressed_snapshot_picture(void) {
+    CameraC328::ErrorNumber err = CameraC328::NoError;
+
+    err = camera.init(CameraC328::Color16bit, CameraC328::RawResolution80x60, CameraC328::JpegResolution80x64);
+    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++) {
+        err = camera.getUncompressedSnapshotPicture(cbfunc);
+        if (CameraC328::NoError == err) {
+            serial.printf("[ OK ] : CameraC328::getUncompressedSnapshotPicture\n");
+        } else {
+            serial.printf("[FAIL] : CameraC328::getUncompressedSnapshotPicture (Error=%02X)\n", (int)err);
+        }
+
+        char fname[64];
+        snprintf(fname, sizeof(fname), "/fs/ucss%04d.ppm", i);
+        FILE *fp = fopen(fname, "w");
+        fprintf(fp, "P3\n");
+        fprintf(fp, "%d %d\n", IMG_X, IMG_Y);
+        fprintf(fp, "%d\n", 255);
+        for (int y = 0; y < IMG_Y; y++) {
+            for (int x = 0; x < IMG_X; x++) {
+                int adrofs = y * (IMG_X * 2) + (x * 2);
+                uint16_t dat = (buf[adrofs + 0] << 8) | (buf[adrofs + 1] << 0);
+                uint8_t r = ((dat >> 11) & 0x1f) << 3;
+                uint8_t g = ((dat >> 5) & 0x3f) << 2;
+                uint8_t b = ((dat >> 0) & 0x1f) << 3;
+                fprintf(fp,"%d %d %d\n", r, g, b);
+            }
+        }
+        fclose(fp);
+    }
+}
+
+void test_uncompressed_preview_picture(void) {
+    CameraC328::ErrorNumber err = CameraC328::NoError;
+
+    err = camera.init(CameraC328::Color16bit, CameraC328::RawResolution80x60, CameraC328::JpegResolution80x64);
+    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++) {
+        err = camera.getUncompressedPreviewPicture(cbfunc);
+        if (CameraC328::NoError == err) {
+            serial.printf("[ OK ] : CameraC328::getUncompressedPreviewPicture\n");
+        } else {
+            serial.printf("[FAIL] : CameraC328::getUncompressedPreviewPicture (Error=%02X)\n", (int)err);
+        }
+
+        char fname[64];
+        snprintf(fname, sizeof(fname), "/fs/ucpv%04d.ppm", i);
+        FILE *fp = fopen(fname, "w");
+        fprintf(fp, "P3\n");
+        fprintf(fp, "%d %d\n", IMG_X, IMG_Y);
+        fprintf(fp, "%d\n", 255);
+        for (int y = 0; y < IMG_Y; y++) {
+            for (int x = 0; x < IMG_X; x++) {
+                int adrofs = y * (IMG_X * 2) + (x * 2);
+                uint16_t dat = (buf[adrofs + 0] << 8) | (buf[adrofs + 1] << 0);
+                uint8_t r = ((dat >> 11) & 0x1f) << 3;
+                uint8_t g = ((dat >> 5) & 0x3f) << 2;
+                uint8_t b = ((dat >> 0) & 0x1f) << 3;
+                fprintf(fp,"%d %d %d\n", r, g, b);
+            }
+        }
+        fclose(fp);
+    }
+}
+
+int main() {
+    serial.baud(19200);
+    serial.printf("\n");
+    serial.printf("==========\n");
+    serial.printf("CameraC328\n");
+    serial.printf("==========\n");
+    
+    sync();
+    test_uncompressed_snapshot_picture();
+    test_uncompressed_preview_picture();
+
+    while (1) {
+        myled1 = 1;
+        wait(0.2);
+        myled1 = 0;
+        wait(0.2);
+        myled2 = 1;
+        wait(0.2);
+        myled2 = 0;
+        wait(0.2);
+    }
+}