CameraC328
Dependents: CameraC328_TestProgram CameraC328_Thresholding Camera_TestProgram_2015 Camera_TestProgram_2015 ... more
Revision 4:ad06342d4b84, committed 2010-06-29
- Comitter:
- shintamainjp
- Date:
- Tue Jun 29 22:55:35 2010 +0000
- Parent:
- 3:6d3150d4396a
- Child:
- 5:5d2088c2433c
- Commit message:
Changed in this revision
--- a/CameraC328.cpp Tue Jun 29 11:45:53 2010 +0000 +++ b/CameraC328.cpp Tue Jun 29 22:55:35 2010 +0000 @@ -1,11 +1,8 @@ /** - * C328-7640 device driver class + * C328-7640 device driver class (Version 0.0.2) * 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/ */ @@ -15,6 +12,8 @@ #define RECVFUNC recvBytes #define WAITFUNC waitRecv +Serial debout(USBTX, USBRX); + CameraC328::CameraC328(PinName tx, PinName rx, Baud baud) : serial(tx, rx) { serial.baud((int)baud); } @@ -56,11 +55,25 @@ return en; } + static bool alreadySetupPackageSize = false; + if (!alreadySetupPackageSize) { + en = sendSetPackageSize(packageSize); + if (NoError != en) { + return en; + } + WAITFUNC(); + en = recvAckOrNck(); + if (NoError != en) { + return en; + } + alreadySetupPackageSize = true; + } + return (ErrorNumber)NoError; } /** - * Get uncompressed snapshot picture (uncompressed snapshot picture) + * Get uncompressed snapshot picture. * * @param func Pointer to a callback function. * @return Status of the error. @@ -121,7 +134,7 @@ } /** - * Get uncompressed snapshot picture (uncompressed snapshot picture) + * Get uncompressed preview picture. * * @param func Pointer to a callback function. * @return Status of the error. @@ -171,6 +184,198 @@ return (ErrorNumber)NoError; } +/** + * Get JPEG snapshot picture. + * + * @param func Pointer to a callback function. + * @return Status of the error. + */ +CameraC328::ErrorNumber CameraC328::getJpegSnapshotPicture(void(*func)(char *buf, size_t siz)) { + + ErrorNumber en; + + en = sendSnapshot(CompressedPicture, 1); + 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; + } + + /* + * Data : snapshot picture + */ + DataType dt; + uint32_t length = 0; + WAITFUNC(); + en = recvData(&dt, &length); + if (NoError != en) { + return en; + } + en = sendAck(0x00, 0); + if (NoError != en) { + return en; + } + + WAITFUNC(); + + char databuf[packageSize - 6]; + uint16_t pkg_total = length / (packageSize - 6); + for (int i = 0; i <= (int)pkg_total; i++) { + uint16_t checksum = 0; + // ID. + char idbuf[2]; + if (!RECVFUNC(idbuf, sizeof(idbuf))) { + return (ErrorNumber)UnexpectedReply; + } + checksum += idbuf[0]; + checksum += idbuf[1]; + uint16_t id = (idbuf[1] << 8) | (idbuf[0] << 0); + if (id != i) { + return (ErrorNumber)UnexpectedReply; + } + + // Size of the data. + char dsbuf[2]; + if (!RECVFUNC(dsbuf, sizeof(dsbuf))) { + return (ErrorNumber)UnexpectedReply; + } + + // Received the data. + checksum += dsbuf[0]; + checksum += dsbuf[1]; + uint16_t ds = (dsbuf[1] << 8) | (dsbuf[0] << 0); + if (!RECVFUNC(&databuf[0], ds)) { + return (ErrorNumber)UnexpectedReply; + } + for (int j = 0; j < ds; j++) { + checksum += databuf[j]; + } + + // Verify code. + char vcbuf[2]; + if (!RECVFUNC(vcbuf, sizeof(vcbuf))) { + return (ErrorNumber)UnexpectedReply; + } + uint16_t vc = (vcbuf[1] << 8) | (vcbuf[0] << 0); + if (vc != (checksum & 0xff)) { + return (ErrorNumber)UnexpectedReply; + } + + func(databuf, ds); + + en = sendAck(0x00, 1 + i); + if (NoError != en) { + return en; + } + } + + return (ErrorNumber)NoError; +} + +/** + * Get JPEG preview picture. + * + * @param func Pointer to a callback function. + * @return Status of the error. + */ +CameraC328::ErrorNumber CameraC328::getJpegPreviewPicture(void(*func)(char *buf, size_t siz)) { + + ErrorNumber en; + + en = sendGetPicture(JpegPreviewPicture); + if (NoError != en) { + return en; + } + WAITFUNC(); + en = recvAckOrNck(); + if (NoError != en) { + return en; + } + + /* + * Data : JPEG preview picture + */ + DataType dt; + uint32_t length = 0; + WAITFUNC(); + en = recvData(&dt, &length); + if (NoError != en) { + return en; + } + en = sendAck(0x00, 0); + if (NoError != en) { + return en; + } + + WAITFUNC(); + + char databuf[packageSize - 6]; + uint16_t pkg_total = length / (packageSize - 6); + for (int i = 0; i <= (int)pkg_total; i++) { + uint16_t checksum = 0; + // ID. + char idbuf[2]; + if (!RECVFUNC(idbuf, sizeof(idbuf))) { + return (ErrorNumber)UnexpectedReply; + } + checksum += idbuf[0]; + checksum += idbuf[1]; + uint16_t id = (idbuf[1] << 8) | (idbuf[0] << 0); + if (id != i) { + return (ErrorNumber)UnexpectedReply; + } + + // Size of the data. + char dsbuf[2]; + if (!RECVFUNC(dsbuf, sizeof(dsbuf))) { + return (ErrorNumber)UnexpectedReply; + } + + // Received the data. + checksum += dsbuf[0]; + checksum += dsbuf[1]; + uint16_t ds = (dsbuf[1] << 8) | (dsbuf[0] << 0); + if (!RECVFUNC(&databuf[0], ds)) { + return (ErrorNumber)UnexpectedReply; + } + for (int j = 0; j < ds; j++) { + checksum += databuf[j]; + } + + // Verify code. + char vcbuf[2]; + if (!RECVFUNC(vcbuf, sizeof(vcbuf))) { + return (ErrorNumber)UnexpectedReply; + } + uint16_t vc = (vcbuf[1] << 8) | (vcbuf[0] << 0); + if (vc != (checksum & 0xff)) { + return (ErrorNumber)UnexpectedReply; + } + + func(databuf, ds); + + en = sendAck(0x00, 1 + i); + if (NoError != en) { + return en; + } + } + + return (ErrorNumber)NoError; +} + CameraC328::ErrorNumber CameraC328::sendInitial(ColorType ct, RawResolution rr, JpegResolution jr) { char send[COMMAND_LENGTH];
--- a/CameraC328.h Tue Jun 29 11:45:53 2010 +0000 +++ b/CameraC328.h Tue Jun 29 22:55:35 2010 +0000 @@ -1,16 +1,16 @@ /** - * C328-7640 device driver class + * C328-7640 device driver class (Version 0.0.2) * 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" +#ifndef _CAMERA_C328_H_ +#define _CAMERA_C328_H_ + class CameraC328 { public: @@ -100,11 +100,14 @@ ErrorNumber init(ColorType ct, RawResolution rr, JpegResolution jr); ErrorNumber getUncompressedSnapshotPicture(void(*func)(size_t done, size_t total, char c)); ErrorNumber getUncompressedPreviewPicture(void(*func)(size_t done, size_t total, char c)); + ErrorNumber getJpegSnapshotPicture(void(*func)(char *buf, size_t siz)); + ErrorNumber getJpegPreviewPicture(void(*func)(char *buf, size_t siz)); private: Serial serial; static const int COMMAND_LENGTH = 6; static const int SYNCMAX = 60; + static const int packageSize = 512; ErrorNumber sendInitial(ColorType ct, RawResolution rr, JpegResolution jr); ErrorNumber sendGetPicture(PictureType pt); @@ -119,7 +122,9 @@ ErrorNumber sendAck(uint8_t commandId, uint16_t packageId); ErrorNumber recvAckOrNck(); - bool sendBytes(char *buf, size_t len, int timeout_us = 5000); - bool recvBytes(char *buf, size_t len, int timeout_us = 5000); + bool sendBytes(char *buf, size_t len, int timeout_us = 20000); + bool recvBytes(char *buf, size_t len, int timeout_us = 20000); bool waitRecv(); }; + +#endif
--- a/main.cpp Tue Jun 29 11:45:53 2010 +0000 +++ b/main.cpp Tue Jun 29 22:55:35 2010 +0000 @@ -1,11 +1,8 @@ /** - * C328-7640 device driver test program + * C328-7640 device driver class (Version 0.0.2) * 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/ */ @@ -20,11 +17,18 @@ const int IMG_X = 80; const int IMG_Y = 60; char buf[IMG_X * IMG_Y * 2]; +FILE *fp_jpeg; -void cbfunc(size_t done, size_t total, char c) { +void uncompressed_callback(size_t done, size_t total, char c) { buf[done - 1] = c; } +void jpeg_callback(char *buf, size_t siz) { + for (int i = 0; i < (int)siz; i++) { + fprintf(fp_jpeg, "%c", buf[i]); + } +} + void sync(void) { CameraC328::ErrorNumber err = CameraC328::NoError; @@ -47,7 +51,7 @@ } for (int i = 0; i < 10; i++) { - err = camera.getUncompressedSnapshotPicture(cbfunc); + err = camera.getUncompressedSnapshotPicture(uncompressed_callback); if (CameraC328::NoError == err) { serial.printf("[ OK ] : CameraC328::getUncompressedSnapshotPicture\n"); } else { @@ -85,7 +89,7 @@ } for (int i = 0; i < 10; i++) { - err = camera.getUncompressedPreviewPicture(cbfunc); + err = camera.getUncompressedPreviewPicture(uncompressed_callback); if (CameraC328::NoError == err) { serial.printf("[ OK ] : CameraC328::getUncompressedPreviewPicture\n"); } else { @@ -112,6 +116,58 @@ } } +void test_jpeg_snapshot_picture(void) { + CameraC328::ErrorNumber err = CameraC328::NoError; + + err = camera.init(CameraC328::Jpeg, CameraC328::RawResolution80x60, CameraC328::JpegResolution640x480); + 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++) { + char fname[64]; + snprintf(fname, sizeof(fname), "/fs/jpss%04d.jpg", i); + fp_jpeg = fopen(fname, "w"); + + err = camera.getJpegSnapshotPicture(jpeg_callback); + if (CameraC328::NoError == err) { + serial.printf("[ OK ] : CameraC328::getJpegSnapshotPicture\n"); + } else { + serial.printf("[FAIL] : CameraC328::getJpegSnapshotPicture (Error=%02X)\n", (int)err); + } + + fclose(fp_jpeg); + } +} + +void test_jpeg_preview_picture(void) { + CameraC328::ErrorNumber err = CameraC328::NoError; + + err = camera.init(CameraC328::Jpeg, CameraC328::RawResolution80x60, CameraC328::JpegResolution640x480); + 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++) { + char fname[64]; + snprintf(fname, sizeof(fname), "/fs/jppv%04d.jpg", i); + fp_jpeg = fopen(fname, "w"); + + err = camera.getJpegPreviewPicture(jpeg_callback); + if (CameraC328::NoError == err) { + serial.printf("[ OK ] : CameraC328::getJpegPreviewPicture\n"); + } else { + serial.printf("[FAIL] : CameraC328::getJpegPreviewPicture (Error=%02X)\n", (int)err); + } + + fclose(fp_jpeg); + } +} + int main() { serial.baud(19200); serial.printf("\n"); @@ -120,8 +176,12 @@ serial.printf("==========\n"); sync(); + #if 0 test_uncompressed_snapshot_picture(); test_uncompressed_preview_picture(); + #endif + test_jpeg_preview_picture(); + test_jpeg_snapshot_picture(); while (1) { myled1 = 1;