CameraC328

Dependents:   CameraC328_TestProgram CameraC328_Thresholding Camera_TestProgram_2015 Camera_TestProgram_2015 ... more

CameraC328.cpp

Committer:
shintamainjp
Date:
2010-06-28
Revision:
2:6a72fcad5c0a
Parent:
1:167e51d598cf
Child:
3:6d3150d4396a

File content as of revision 2:6a72fcad5c0a:

#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), syncdone(false) {
    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))) {
                                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;
                            }
                        }
                    }
                }
            }
        }
        wait(0.200);
    }
    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;
    }

    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)) {

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

    /*
     * Snapshot (uncompressed picture)
     */
    send[0] = 0xAA;
    send[1] = 0x05;
    send[2] = (char)UncompressedPicture;
    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 (snapshot picture)
     */

    send[0] = 0xAA;
    send[1] = 0x04;
    send[2] = (char)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];
    }

    /*
     * image data
     */
    while (!serial.readable()) {
    }
    if (!RECVFUNC(recv, sizeof(recv))) {
        return (ErrorNumber)UnexpectedReply;
    }
    if ((0xAA != recv[0]) || (0x0A != recv[1])) {
        return (ErrorNumber)recv[4];
    }
    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);
    }

    /*
     * ACK
     */
    send[0] = 0xAA;
    send[1] = 0x0E;
    send[2] = 0x0A;
    send[3] = 0x00;
    send[4] = 0x00;
    send[5] = 0x00;
    if (!SENDFUNC(send, sizeof(send))) {
        return (ErrorNumber)SendRegisterTimeout;
    }

    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 (uint32_t i = 0; i < (uint32_t)len; i++) {
        int cnt = 0;
        while (!serial.writeable()) {
            wait(0.000001);
            cnt++;
            if (TIMEOUT_US < cnt) {
                return false;
            }
        }
        serial.putc(buf[i]);
    }
    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 (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.
 * @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 (uint32_t i = 0; i < (uint32_t)len; i++) {
        int cnt = 0;
        while (!serial.readable()) {
            wait(0.000001);
            cnt++;
            if (TIMEOUT_US < cnt) {
                debout.printf(" [Timed out]\n");
                return false;
            }
        }
        buf[i] = serial.getc();
        debout.printf(" %02X", buf[i]);
    }
    debout.printf(" [OK]\n");
    return true;
}