CameraC328
Dependents: CameraC328_TestProgram CameraC328_Thresholding Camera_TestProgram_2015 Camera_TestProgram_2015 ... more
Revision 0:7e51c3176eb7, committed 2010-06-27
- Comitter:
- shintamainjp
- Date:
- Sun Jun 27 03:36:10 2010 +0000
- Child:
- 1:167e51d598cf
- Commit message:
Changed in this revision
--- /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