CameraC328

Dependents:   CameraC328_TestProgram CameraC328_Thresholding Camera_TestProgram_2015 Camera_TestProgram_2015 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CameraC328.cpp Source File

CameraC328.cpp

00001 /**
00002  * C328-7640 device driver class (Version 0.0.6)
00003  * Reference documents: C328-7640 User Manual v3.0 2004.8.19
00004  *
00005  * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
00006  * http://shinta.main.jp/
00007  */
00008 
00009 #include "CameraC328.h"
00010 
00011 #define WAITIDLE    waitIdle
00012 #define SENDFUNC    sendBytes
00013 #define RECVFUNC    recvBytes
00014 #define WAITFUNC    waitRecv
00015 
00016 /**
00017  * Constructor.
00018  *
00019  * @param tx A pin for transmit.
00020  * @param rx A pin for receive.
00021  * @param baud Baud rate. (Default is Baud19200.)
00022  */
00023 CameraC328::CameraC328(PinName tx, PinName rx, Baud baud) : serial(tx, rx) {
00024     serial.baud((int)baud);
00025 }
00026 
00027 /**
00028  * Destructor.
00029  */
00030 CameraC328::~CameraC328() {
00031 }
00032 
00033 /**
00034  * Make a sync. for baud rate.
00035  */
00036 CameraC328::ErrorNumber CameraC328::sync() {
00037     WAITIDLE();
00038 
00039     for (int i = 0; i < SYNCMAX; i++) {
00040         if (NoError == sendSync()) {
00041             if (NoError == recvAckOrNck()) {
00042                 if (NoError == recvSync()) {
00043                     if (NoError == sendAck(0x0D, 0x00)) {
00044                         /*
00045                          * After synchronization, the camera needs a little time for AEC and AGC to be stable.
00046                          * Users should wait for 1-2 seconds before capturing the first picture.
00047                          */
00048                         wait(2);
00049                         return NoError;
00050                     }
00051                 }
00052             }
00053         }
00054         wait_ms(50);
00055     }
00056     return UnexpectedReply;
00057 }
00058 
00059 /**
00060  * Initialize.
00061  *
00062  * @param ct Color type.
00063  * @param rr Raw resolution.
00064  * @param jr JPEG resolution.
00065  */
00066 CameraC328::ErrorNumber CameraC328::init(ColorType ct, RawResolution rr, JpegResolution jr) {
00067     WAITIDLE();
00068     ErrorNumber en;
00069 
00070     en = sendInitial(ct, rr, jr);
00071     if (NoError != en) {
00072         return en;
00073     }
00074     WAITFUNC();
00075     en = recvAckOrNck();
00076     if (NoError != en) {
00077         return en;
00078     }
00079 
00080     static bool alreadySetupPackageSize = false;
00081     if (!alreadySetupPackageSize) {
00082         en = sendSetPackageSize(packageSize);
00083         if (NoError != en) {
00084             return en;
00085         }
00086         WAITFUNC();
00087         en = recvAckOrNck();
00088         if (NoError != en) {
00089             return en;
00090         }
00091         alreadySetupPackageSize = true;
00092     }
00093 
00094     return (ErrorNumber)NoError;
00095 }
00096 
00097 /**
00098  * Get uncompressed snapshot picture.
00099  *
00100  * @param func A pointer to a callback function.
00101  *             Please do NOT block this callback function.
00102  *             Because the camera module transmit image datas continuously.
00103  * @return Status of the error.
00104  */
00105 CameraC328::ErrorNumber CameraC328::getUncompressedSnapshotPicture(void(*func)(size_t done, size_t total, char c)) {
00106     WAITIDLE();
00107     ErrorNumber en;
00108 
00109     en = sendSnapshot(UncompressedPicture, 0);
00110     if (NoError != en) {
00111         return en;
00112     }
00113     WAITFUNC();
00114     en = recvAckOrNck();
00115     if (NoError != en) {
00116         return en;
00117     }
00118 
00119     en = sendGetPicture(SnapshotPicture);
00120     if (NoError != en) {
00121         return en;
00122     }
00123     WAITFUNC();
00124     en = recvAckOrNck();
00125     if (NoError != en) {
00126         return en;
00127     }
00128 
00129     /*
00130      * image data
00131      */
00132     DataType dt;
00133     uint32_t length = 0;
00134     WAITFUNC();
00135     en = recvData(&dt, &length);
00136     if (NoError != en) {
00137         return en;
00138     }
00139     size_t imgcnt = 0;
00140     for (int i = 0; i < (int)length; i++) {
00141         char c;
00142         WAITFUNC();
00143         if (!RECVFUNC(&c, 1)) {
00144             return (ErrorNumber)UnexpectedReply;
00145         }
00146         imgcnt++;
00147 
00148         /*
00149          * Call a call back function.
00150          * Please do not block this function.
00151          */
00152         func(imgcnt, length, c);
00153     }
00154 
00155     /*
00156      * ACK
00157      */
00158     en = sendAck(0x0A, 0x00);
00159     if (NoError != en) {
00160         return en;
00161     }
00162 
00163     return (ErrorNumber)NoError;
00164 }
00165 
00166 /**
00167  * Get uncompressed preview picture.
00168  *
00169  * @param func A pointer to a callback function.
00170  *             Please do NOT block this callback function.
00171  *             Because the camera module transmit image datas continuously.
00172  * @return Status of the error.
00173  */
00174 CameraC328::ErrorNumber CameraC328::getUncompressedPreviewPicture(void(*func)(size_t done, size_t total, char c)) {
00175     WAITIDLE();
00176     ErrorNumber en;
00177 
00178     en = sendGetPicture(PreviewPicture);
00179     if (NoError != en) {
00180         return en;
00181     }
00182     WAITFUNC();
00183     en = recvAckOrNck();
00184     if (NoError != en) {
00185         return en;
00186     }
00187 
00188     /*
00189      * image data
00190      */
00191     DataType dt;
00192     uint32_t length = 0;
00193     WAITFUNC();
00194     en = recvData(&dt, &length);
00195     if (NoError != en) {
00196         return en;
00197     }
00198     size_t imgcnt = 0;
00199     for (int i = 0; i < (int)length; i++) {
00200         char c;
00201         WAITFUNC();
00202         if (!RECVFUNC(&c, 1)) {
00203             return (ErrorNumber)UnexpectedReply;
00204         }
00205         imgcnt++;
00206 
00207         /*
00208          * Call a call back function.
00209          * Please do not block this function.
00210          */
00211         func(imgcnt, length, c);
00212     }
00213 
00214     /*
00215      * ACK
00216      */
00217     en = sendAck(0x0A, 0x00);
00218     if (NoError != en) {
00219         return en;
00220     }
00221 
00222     return (ErrorNumber)NoError;
00223 }
00224 
00225 /**
00226  * Get JPEG snapshot picture.
00227  *
00228  * @param func A pointer to a callback function.
00229  *             You can block this function until saving the image datas.
00230  * @return Status of the error.
00231  */
00232 CameraC328::ErrorNumber CameraC328::getJpegSnapshotPicture(void(*func)(char *buf, size_t siz)) {
00233     WAITIDLE();
00234     ErrorNumber en;
00235 
00236     en = sendSnapshot(CompressedPicture, 1);
00237     if (NoError != en) {
00238         return en;
00239     }
00240     WAITFUNC();
00241     en = recvAckOrNck();
00242     if (NoError != en) {
00243         return en;
00244     }
00245 
00246     en = sendGetPicture(SnapshotPicture);
00247     if (NoError != en) {
00248         return en;
00249     }
00250     WAITFUNC();
00251     en = recvAckOrNck();
00252     if (NoError != en) {
00253         return en;
00254     }
00255 
00256     /*
00257      * Data : snapshot picture
00258      */
00259     DataType dt;
00260     uint32_t length = 0;
00261     WAITFUNC();
00262     en = recvData(&dt, &length);
00263     if (NoError != en) {
00264         return en;
00265     }
00266     en = sendAck(0x00, 0);
00267     if (NoError != en) {
00268         return en;
00269     }
00270 
00271     char databuf[packageSize - 6];
00272     uint16_t pkg_total = length / (packageSize - 6);
00273     for (int i = 0; i <= (int)pkg_total; i++) {
00274         uint16_t checksum = 0;
00275         // ID.
00276         char idbuf[2];
00277         WAITFUNC();
00278         if (!RECVFUNC(idbuf, sizeof(idbuf))) {
00279             return (ErrorNumber)UnexpectedReply;
00280         }
00281         checksum += idbuf[0];
00282         checksum += idbuf[1];
00283         uint16_t id = (idbuf[1] << 8) | (idbuf[0] << 0);
00284         if (id != i) {
00285             return (ErrorNumber)UnexpectedReply;
00286         }
00287 
00288         // Size of the data.
00289         char dsbuf[2];
00290         WAITFUNC();
00291         if (!RECVFUNC(dsbuf, sizeof(dsbuf))) {
00292             return (ErrorNumber)UnexpectedReply;
00293         }
00294 
00295         // Received the data.
00296         checksum += dsbuf[0];
00297         checksum += dsbuf[1];
00298         uint16_t ds = (dsbuf[1] << 8) | (dsbuf[0] << 0);
00299         WAITFUNC();
00300         if (!RECVFUNC(&databuf[0], ds)) {
00301             return (ErrorNumber)UnexpectedReply;
00302         }
00303         for (int j = 0; j < ds; j++) {
00304             checksum += databuf[j];
00305         }
00306 
00307         // Verify code.
00308         char vcbuf[2];
00309         WAITFUNC();
00310         if (!RECVFUNC(vcbuf, sizeof(vcbuf))) {
00311             return (ErrorNumber)UnexpectedReply;
00312         }
00313         uint16_t vc = (vcbuf[1] << 8) | (vcbuf[0] << 0);
00314         if (vc != (checksum & 0xff)) {
00315             return (ErrorNumber)UnexpectedReply;
00316         }
00317 
00318         /*
00319          * Call a call back function.
00320          * You can block this function while working.
00321          */
00322         func(databuf, ds);
00323 
00324         /*
00325          * We should wait for camera working before reply a ACK.
00326          */
00327         wait_ms(100);
00328         en = sendAck(0x00, 1 + i);
00329         if (NoError != en) {
00330             return en;
00331         }
00332     }
00333 
00334     return (ErrorNumber)NoError;
00335 }
00336 
00337 /**
00338  * Get JPEG preview picture.
00339  *
00340  * @param func A pointer to a callback function.
00341  *             You can block this function until saving the image datas.
00342  * @return Status of the error.
00343  */
00344 CameraC328::ErrorNumber CameraC328::getJpegPreviewPicture(void(*func)(char *buf, size_t siz)) {
00345     WAITIDLE();
00346     ErrorNumber en;
00347 
00348     en = sendGetPicture(JpegPreviewPicture);
00349     if (NoError != en) {
00350         return en;
00351     }
00352     WAITFUNC();
00353     en = recvAckOrNck();
00354     if (NoError != en) {
00355         return en;
00356     }
00357 
00358     /*
00359      * Data : JPEG preview picture
00360      */
00361     DataType dt;
00362     uint32_t length = 0;
00363     WAITFUNC();
00364     en = recvData(&dt, &length);
00365     if (NoError != en) {
00366         return en;
00367     }
00368     en = sendAck(0x00, 0);
00369     if (NoError != en) {
00370         return en;
00371     }
00372 
00373     char databuf[packageSize - 6];
00374     uint16_t pkg_total = length / (packageSize - 6);
00375     for (int i = 0; i <= (int)pkg_total; i++) {
00376         uint16_t checksum = 0;
00377         // ID.
00378         char idbuf[2];
00379         WAITFUNC();
00380         if (!RECVFUNC(idbuf, sizeof(idbuf))) {
00381             return (ErrorNumber)UnexpectedReply;
00382         }
00383         checksum += idbuf[0];
00384         checksum += idbuf[1];
00385         uint16_t id = (idbuf[1] << 8) | (idbuf[0] << 0);
00386         if (id != i) {
00387             return (ErrorNumber)UnexpectedReply;
00388         }
00389 
00390         // Size of the data.
00391         char dsbuf[2];
00392         WAITFUNC();
00393         if (!RECVFUNC(dsbuf, sizeof(dsbuf))) {
00394             return (ErrorNumber)UnexpectedReply;
00395         }
00396 
00397         // Received the data.
00398         checksum += dsbuf[0];
00399         checksum += dsbuf[1];
00400         uint16_t ds = (dsbuf[1] << 8) | (dsbuf[0] << 0);
00401         WAITFUNC();
00402         if (!RECVFUNC(&databuf[0], ds)) {
00403             return (ErrorNumber)UnexpectedReply;
00404         }
00405         for (int j = 0; j < ds; j++) {
00406             checksum += databuf[j];
00407         }
00408 
00409         // Verify code.
00410         char vcbuf[2];
00411         WAITFUNC();
00412         if (!RECVFUNC(vcbuf, sizeof(vcbuf))) {
00413             return (ErrorNumber)UnexpectedReply;
00414         }
00415         uint16_t vc = (vcbuf[1] << 8) | (vcbuf[0] << 0);
00416         if (vc != (checksum & 0xff)) {
00417             return (ErrorNumber)UnexpectedReply;
00418         }
00419 
00420         /*
00421          * Call a call back function.
00422          * You can block this function while working.
00423          */
00424         func(databuf, ds);
00425 
00426         /*
00427          * We should wait for camera working before reply a ACK.
00428          */
00429         wait_ms(100);
00430         en = sendAck(0x00, 1 + i);
00431         if (NoError != en) {
00432             return en;
00433         }
00434     }
00435 
00436     return (ErrorNumber)NoError;
00437 }
00438 
00439 CameraC328::ErrorNumber CameraC328::sendInitial(ColorType ct, RawResolution rr, JpegResolution jr) {
00440     char send[COMMAND_LENGTH];
00441 
00442     send[0] = 0xAA;
00443     send[1] = 0x01;
00444     send[2] = 0x00;
00445     send[3] = (char)ct;
00446     send[4] = (char)rr;
00447     send[5] = (char)jr;
00448 
00449     if (!SENDFUNC(send, sizeof(send))) {
00450         return (ErrorNumber)SendRegisterTimeout;
00451     }
00452     return (ErrorNumber)NoError;
00453 }
00454 
00455 CameraC328::ErrorNumber CameraC328::sendGetPicture(PictureType pt) {
00456     char send[COMMAND_LENGTH];
00457 
00458     send[0] = 0xAA;
00459     send[1] = 0x04;
00460     send[2] = (char)pt;
00461     send[3] = 0x00;
00462     send[4] = 0x00;
00463     send[5] = 0x00;
00464 
00465     if (!SENDFUNC(send, sizeof(send))) {
00466         return (ErrorNumber)SendRegisterTimeout;
00467     }
00468     return (ErrorNumber)NoError;
00469 }
00470 
00471 CameraC328::ErrorNumber CameraC328::sendSnapshot(SnapshotType st, uint16_t skipFrames) {
00472     char send[COMMAND_LENGTH];
00473     send[0] = 0xAA;
00474     send[1] = 0x05;
00475     send[2] = (char)st;
00476     send[3] = (skipFrames >> 0) & 0xff;
00477     send[4] = (skipFrames >> 8) & 0xff;
00478     send[5] = 0x00;
00479 
00480     if (!SENDFUNC(send, sizeof(send))) {
00481         return (ErrorNumber)SendRegisterTimeout;
00482     }
00483     return (ErrorNumber)NoError;
00484 }
00485 
00486 CameraC328::ErrorNumber CameraC328::sendSetPackageSize(uint16_t packageSize) {
00487     char send[COMMAND_LENGTH];
00488     send[0] = 0xAA;
00489     send[1] = 0x06;
00490     send[2] = 0x08;
00491     send[3] = (packageSize >> 0) & 0xff;
00492     send[4] = (packageSize >> 8) & 0xff;
00493     send[5] = 0x00;
00494 
00495     if (!SENDFUNC(send, sizeof(send))) {
00496         return (ErrorNumber)SendRegisterTimeout;
00497     }
00498     return (ErrorNumber)NoError;
00499 }
00500 
00501 CameraC328::ErrorNumber CameraC328::sendSetBaudrate(Baud baud) {
00502     char send[COMMAND_LENGTH];
00503 
00504     static struct baud_list {
00505         Baud baud;
00506         uint8_t div1st;
00507         uint8_t div2nd;
00508     } baudtable [] = {
00509         { Baud7200, 0xff, 0x01 },
00510         { Baud9600, 0xbf, 0x01 },
00511         { Baud14400, 0x7f, 0x01 },
00512         { Baud19200, 0x5f, 0x01 },
00513         { Baud28800, 0x3f, 0x01 },
00514         { Baud38400, 0x2f, 0x01 },
00515         { Baud57600, 0x1f, 0x01 },
00516         { Baud115200, 0x0f, 0x01 }
00517     };
00518 
00519     uint8_t div1st = 0x00, div2nd = 0x00;
00520     struct baud_list *p = &baudtable[0];
00521     for (int i = 0; i < sizeof(baudtable) / sizeof(baudtable[0]); i++) {
00522         if (p->baud == baud) {
00523             div1st = p->div1st;
00524             div2nd = p->div2nd;
00525         }
00526         p++;
00527     }
00528 
00529     send[0] = 0xAA;
00530     send[1] = 0x07;
00531     send[2] = div1st;
00532     send[3] = div2nd;
00533     send[4] = 0x00;
00534     send[5] = 0x00;
00535 
00536     if (!SENDFUNC(send, sizeof(send))) {
00537         return (ErrorNumber)SendRegisterTimeout;
00538     }
00539 
00540     return (ErrorNumber)NoError;
00541 }
00542 
00543 CameraC328::ErrorNumber CameraC328::sendReset(ResetType rt, bool specialReset) {
00544     char send[COMMAND_LENGTH];
00545     send[0] = 0xAA;
00546     send[1] = 0x08;
00547     send[2] = (int)rt;
00548     send[3] = 0x00;
00549     send[4] = 0x00;
00550     send[5] = specialReset ? 0xff : 0x00;
00551     /*
00552      * Special reset : If the parameter is 0xFF, the command is a special Reset command and the firmware responds to it immediately.
00553      */
00554 
00555     if (!SENDFUNC(send, sizeof(send))) {
00556         return (ErrorNumber)SendRegisterTimeout;
00557     }
00558 
00559     return (ErrorNumber)NoError;
00560 }
00561 
00562 CameraC328::ErrorNumber CameraC328::sendPowerOff() {
00563     char send[COMMAND_LENGTH];
00564     send[0] = 0xAA;
00565     send[1] = 0x09;
00566     send[2] = 0x00;
00567     send[3] = 0x00;
00568     send[4] = 0x00;
00569     send[5] = 0x00;
00570 
00571     if (!SENDFUNC(send, sizeof(send))) {
00572         return (ErrorNumber)SendRegisterTimeout;
00573     }
00574 
00575     return (ErrorNumber)NoError;
00576 }
00577 
00578 CameraC328::ErrorNumber CameraC328::recvData(DataType *dt, uint32_t *length) {
00579     char recv[COMMAND_LENGTH];
00580     if (!RECVFUNC(recv, sizeof(recv))) {
00581         return (ErrorNumber)UnexpectedReply;
00582     }
00583     if ((0xAA != recv[0]) || (0x0A != recv[1])) {
00584         return (ErrorNumber)UnexpectedReply;
00585     }
00586     *dt = (DataType)recv[2];
00587     *length = (recv[5] << 16) | (recv[4] << 8) | (recv[3] << 0);
00588     return (ErrorNumber)NoError;
00589 }
00590 
00591 CameraC328::ErrorNumber CameraC328::sendSync() {
00592     char send[COMMAND_LENGTH];
00593     send[0] = 0xAA;
00594     send[1] = 0x0D;
00595     send[2] = 0x00;
00596     send[3] = 0x00;
00597     send[4] = 0x00;
00598     send[5] = 0x00;
00599     if (!SENDFUNC(send, sizeof(send))) {
00600         return (ErrorNumber)SendRegisterTimeout;
00601     }
00602     return (ErrorNumber)NoError;
00603 }
00604 
00605 CameraC328::ErrorNumber CameraC328::recvSync() {
00606     char recv[COMMAND_LENGTH];
00607     if (!RECVFUNC(recv, sizeof(recv))) {
00608         return (ErrorNumber)UnexpectedReply;
00609     }
00610     if ((0xAA != recv[0]) || (0x0D != recv[1])) {
00611         return (ErrorNumber)UnexpectedReply;
00612     }
00613     return (ErrorNumber)NoError;
00614 }
00615 
00616 /**
00617  * Send ACK.
00618  *
00619  * @param commandId The command with that ID is acknowledged by this command.
00620  * @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.
00621  */
00622 CameraC328::ErrorNumber CameraC328::sendAck(uint8_t commandId, uint16_t packageId) {
00623     char send[COMMAND_LENGTH];
00624     send[0] = 0xAA;
00625     send[1] = 0x0E;
00626     send[2] = commandId;
00627     send[3] = 0x00;    // ACK counter is not used.
00628     send[4] = (packageId >> 0) & 0xff;
00629     send[5] = (packageId >> 8) & 0xff;
00630     if (!SENDFUNC(send, sizeof(send))) {
00631         return (ErrorNumber)SendRegisterTimeout;
00632     }
00633     return (ErrorNumber)NoError;
00634 }
00635 
00636 /**
00637  * Receive ACK or NCK.
00638  *
00639  * @return Error number.
00640  */
00641 CameraC328::ErrorNumber CameraC328::recvAckOrNck() {
00642     char recv[COMMAND_LENGTH];
00643     if (!RECVFUNC(recv, sizeof(recv))) {
00644         return (ErrorNumber)UnexpectedReply;
00645     }
00646     if ((0xAA == recv[0]) && (0x0E == recv[1])) {
00647         return (ErrorNumber)NoError;
00648     }
00649     if ((0xAA == recv[0]) && (0x0F == recv[1])) {
00650         return (ErrorNumber)recv[4];
00651     }
00652     return (ErrorNumber)UnexpectedReply;
00653 }
00654 
00655 /**
00656  * Send bytes to camera module.
00657  *
00658  * @param buf Pointer to the data buffer.
00659  * @param len Length of the data buffer.
00660  *
00661  * @return True if the data sended.
00662  */
00663 bool CameraC328::sendBytes(char *buf, size_t len, int timeout_us) {
00664     for (uint32_t i = 0; i < (uint32_t)len; i++) {
00665         int cnt = 0;
00666         while (!serial.writeable()) {
00667             wait_us(1);
00668             cnt++;
00669             if (timeout_us < cnt) {
00670                 return false;
00671             }
00672         }
00673         serial.putc(buf[i]);
00674     }
00675     return true;
00676 }
00677 
00678 /**
00679  * Receive bytes from camera module.
00680  *
00681  * @param buf Pointer to the data buffer.
00682  * @param len Length of the data buffer.
00683  *
00684  * @return True if the data received.
00685  */
00686 bool CameraC328::recvBytes(char *buf, size_t len, int timeout_us) {
00687     for (uint32_t i = 0; i < (uint32_t)len; i++) {
00688         int cnt = 0;
00689         while (!serial.readable()) {
00690             wait_us(1);
00691             cnt++;
00692             if (timeout_us < cnt) {
00693                 return false;
00694             }
00695         }
00696         buf[i] = serial.getc();
00697     }
00698     return true;
00699 }
00700 
00701 /**
00702  * Wait received.
00703  *
00704  * @return True if the data received.
00705  */
00706 bool CameraC328::waitRecv() {
00707     while (!serial.readable()) {
00708     }
00709     return true;
00710 }
00711 
00712 /**
00713  * Wait idle state.
00714  */
00715 bool CameraC328::waitIdle() {
00716     while (serial.readable()) {
00717         serial.getc();
00718     }
00719     return true;
00720 }