CameraC328

Dependents:   CameraC328_TestProgram CameraC328_Thresholding Camera_TestProgram_2015 Camera_TestProgram_2015 ... more

CameraC328.cpp

Committer:
shintamainjp
Date:
2010-06-27
Revision:
1:167e51d598cf
Parent:
0:7e51c3176eb7
Child:
2:6a72fcad5c0a

File content as of revision 1:167e51d598cf:

#include "CameraC328.h"

Serial debout(USBTX, USBRX);

#if 0
#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::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 JPEG 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)) {

    char send[COMMAND_LENGTH];
    char recv[COMMAND_LENGTH];

    /*
     * Set Package Size
     */

    size_t pkgsiz = 512;
    send[0] = 0xAA;
    send[1] = 0x06;
    send[2] = 0x08;
    send[3] = (char)(pkgsiz >> 8);
    send[4] = (char)(pkgsiz >> 0);
    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];
    }

    /*
     * Snapshot (compressed picture)
     */

    send[0] = 0xAA;
    send[1] = 0x05;
    send[2] = 0x00;
    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];
    }

    /*
     * Get picture
     */

    send[0] = 0xAA;
    send[1] = 0x04;
    send[2] = 0x01;
    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];
    }
    if (!RECVFUNC(recv, sizeof(recv))) {
        return (ErrorNumber)UnexpectedReply;
    }
    if ((0xAA != recv[0]) || (0x0A != recv[1])) {
        return (ErrorNumber)UnexpectedReply;
    }

    /*
     * ACK package ID
     */
    char pkghead[4];
    char pkgtail[2];
    size_t imgsiz = (recv[5] << (8 * 2)) | (recv[4] << (8 * 1)) | (recv[3] << (8 * 0));
    size_t rcvcnt = 0;
    size_t pkgcnt = 0;
    while (rcvcnt < imgsiz) {
        send[0] = 0xAA;
        send[1] = 0x0E;
        send[2] = 0x00;
        send[3] = 0x00;
        send[4] = (char)(pkgcnt >> 0);
        send[5] = (char)(pkgcnt >> 8);
        if (!SENDFUNC(send, sizeof(send))) {
            return (ErrorNumber)SendRegisterTimeout;
        }
        wait(1);
        if (!RECVFUNC(pkghead, sizeof(pkghead))) {
            return (ErrorNumber)UnexpectedReply;
        }
        int id = (pkghead[1] << 8) | (pkghead[0] << 0);
        int sz = (pkghead[3] << 8) | (pkghead[2] << 0);
        debout.printf("Received/Total %d/%d bytes, Current package data size is %d.\n", rcvcnt, imgsiz, sz);
        char pkgdata[pkgsiz];
        if (!RECVFUNC(pkgdata, sizeof(pkgdata))) {
            return (ErrorNumber)UnexpectedReply;
        }
        if (!RECVFUNC(pkgtail, sizeof(pkgtail))) {
            return (ErrorNumber)UnexpectedReply;
        }
        rcvcnt+=sz;
        pkgcnt++;
    }

    return (ErrorNumber)NoError;
}

/**
 * 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;
}