CameraC328
Dependents: CameraC328_TestProgram CameraC328_Thresholding Camera_TestProgram_2015 Camera_TestProgram_2015 ... more
Revision 3:6d3150d4396a, committed 2010-06-29
- Comitter:
- shintamainjp
- Date:
- Tue Jun 29 11:45:53 2010 +0000
- Parent:
- 2:6a72fcad5c0a
- Child:
- 4:ad06342d4b84
- Commit message:
Changed in this revision
--- 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); + } +}