IOP WIZnet / CameraC328

Dependents:   Camera_C328_HTTP_SDcard_file_server_WIZwiki-W7500

Fork of CameraC328 by Shinichiro Nakamura

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     
00274     for (int i = 0; i <= (int)pkg_total; i++) {        
00275         
00276         printf(".\r\n");    // check it on the processing
00277         
00278         uint16_t checksum = 0;
00279         // ID.
00280         char idbuf[2];
00281         WAITFUNC();
00282         if (!RECVFUNC(idbuf, sizeof(idbuf))) {
00283             return (ErrorNumber)UnexpectedReply;
00284         }
00285         checksum += idbuf[0];
00286         checksum += idbuf[1];
00287         uint16_t id = (idbuf[1] << 8) | (idbuf[0] << 0);
00288         if (id != i) {
00289             return (ErrorNumber)UnexpectedReply;
00290         }
00291 
00292         // Size of the data.
00293         char dsbuf[2];
00294         WAITFUNC();
00295         if (!RECVFUNC(dsbuf, sizeof(dsbuf))) {
00296             return (ErrorNumber)UnexpectedReply;
00297         }
00298 
00299         // Received the data.
00300         checksum += dsbuf[0];
00301         checksum += dsbuf[1];
00302         uint16_t ds = (dsbuf[1] << 8) | (dsbuf[0] << 0);
00303         WAITFUNC();
00304         if (!RECVFUNC(&databuf[0], ds)) {
00305             return (ErrorNumber)UnexpectedReply;
00306         }
00307         for (int j = 0; j < ds; j++) {
00308             checksum += databuf[j];
00309         }
00310 
00311         // Verify code.
00312         char vcbuf[2];
00313         WAITFUNC();
00314         if (!RECVFUNC(vcbuf, sizeof(vcbuf))) {
00315             return (ErrorNumber)UnexpectedReply;
00316         }
00317         uint16_t vc = (vcbuf[1] << 8) | (vcbuf[0] << 0);
00318         if (vc != (checksum & 0xff)) {
00319             return (ErrorNumber)UnexpectedReply;
00320         }
00321 
00322         /*
00323          * Call a call back function.
00324          * You can block this function while working.
00325          */
00326         func(databuf, ds);
00327 
00328         /*
00329          * We should wait for camera working before reply a ACK.
00330          */
00331         wait_ms(100);
00332         en = sendAck(0x00, 1 + i);
00333         if (NoError != en) {
00334             return en;
00335         }      
00336     }
00337     return (ErrorNumber)NoError;
00338 }
00339 
00340 /**
00341  * Get JPEG preview picture.
00342  *
00343  * @param func A pointer to a callback function.
00344  *             You can block this function until saving the image datas.
00345  * @return Status of the error.
00346  */
00347 CameraC328::ErrorNumber CameraC328::getJpegPreviewPicture(void(*func)(char *buf, size_t siz)) {
00348     WAITIDLE();
00349     ErrorNumber en;
00350 
00351     en = sendGetPicture(JpegPreviewPicture);
00352     if (NoError != en) {
00353         return en;
00354     }
00355     WAITFUNC();
00356     en = recvAckOrNck();
00357     if (NoError != en) {
00358         return en;
00359     }
00360 
00361     /*
00362      * Data : JPEG preview picture
00363      */
00364     DataType dt;
00365     uint32_t length = 0;
00366     WAITFUNC();
00367     en = recvData(&dt, &length);
00368     if (NoError != en) {
00369         return en;
00370     }
00371     en = sendAck(0x00, 0);
00372     if (NoError != en) {
00373         return en;
00374     }
00375 
00376     char databuf[packageSize - 6];
00377     uint16_t pkg_total = length / (packageSize - 6);
00378     for (int i = 0; i <= (int)pkg_total; i++) {
00379         uint16_t checksum = 0;
00380         // ID.
00381         char idbuf[2];
00382         WAITFUNC();
00383         if (!RECVFUNC(idbuf, sizeof(idbuf))) {
00384             return (ErrorNumber)UnexpectedReply;
00385         }
00386         checksum += idbuf[0];
00387         checksum += idbuf[1];
00388         uint16_t id = (idbuf[1] << 8) | (idbuf[0] << 0);
00389         if (id != i) {
00390             return (ErrorNumber)UnexpectedReply;
00391         }
00392 
00393         // Size of the data.
00394         char dsbuf[2];
00395         WAITFUNC();
00396         if (!RECVFUNC(dsbuf, sizeof(dsbuf))) {
00397             return (ErrorNumber)UnexpectedReply;
00398         }
00399 
00400         // Received the data.
00401         checksum += dsbuf[0];
00402         checksum += dsbuf[1];
00403         uint16_t ds = (dsbuf[1] << 8) | (dsbuf[0] << 0);
00404         WAITFUNC();
00405         if (!RECVFUNC(&databuf[0], ds)) {
00406             return (ErrorNumber)UnexpectedReply;
00407         }
00408         for (int j = 0; j < ds; j++) {
00409             checksum += databuf[j];
00410         }
00411 
00412         // Verify code.
00413         char vcbuf[2];
00414         WAITFUNC();
00415         if (!RECVFUNC(vcbuf, sizeof(vcbuf))) {
00416             return (ErrorNumber)UnexpectedReply;
00417         }
00418         uint16_t vc = (vcbuf[1] << 8) | (vcbuf[0] << 0);
00419         if (vc != (checksum & 0xff)) {
00420             return (ErrorNumber)UnexpectedReply;
00421         }
00422 
00423         /*
00424          * Call a call back function.
00425          * You can block this function while working.
00426          */
00427         func(databuf, ds);
00428 
00429         /*
00430          * We should wait for camera working before reply a ACK.
00431          */
00432         wait_ms(100);
00433         en = sendAck(0x00, 1 + i);
00434         if (NoError != en) {
00435             return en;
00436         }
00437     }
00438 
00439     return (ErrorNumber)NoError;
00440 }
00441 
00442 CameraC328::ErrorNumber CameraC328::sendInitial(ColorType ct, RawResolution rr, JpegResolution jr) {
00443     char send[COMMAND_LENGTH];
00444 
00445     send[0] = 0xAA;
00446     send[1] = 0x01;
00447     send[2] = 0x00;
00448     send[3] = (char)ct;
00449     send[4] = (char)rr;
00450     send[5] = (char)jr;
00451 
00452     if (!SENDFUNC(send, sizeof(send))) {
00453         return (ErrorNumber)SendRegisterTimeout;
00454     }
00455     return (ErrorNumber)NoError;
00456 }
00457 
00458 CameraC328::ErrorNumber CameraC328::sendGetPicture(PictureType pt) {
00459     char send[COMMAND_LENGTH];
00460 
00461     send[0] = 0xAA;
00462     send[1] = 0x04;
00463     send[2] = (char)pt;
00464     send[3] = 0x00;
00465     send[4] = 0x00;
00466     send[5] = 0x00;
00467 
00468     if (!SENDFUNC(send, sizeof(send))) {
00469         return (ErrorNumber)SendRegisterTimeout;
00470     }
00471     return (ErrorNumber)NoError;
00472 }
00473 
00474 CameraC328::ErrorNumber CameraC328::sendSnapshot(SnapshotType st, uint16_t skipFrames) {
00475     char send[COMMAND_LENGTH];
00476     send[0] = 0xAA;
00477     send[1] = 0x05;
00478     send[2] = (char)st;
00479     send[3] = (skipFrames >> 0) & 0xff;
00480     send[4] = (skipFrames >> 8) & 0xff;
00481     send[5] = 0x00;
00482 
00483     if (!SENDFUNC(send, sizeof(send))) {
00484         return (ErrorNumber)SendRegisterTimeout;
00485     }
00486     return (ErrorNumber)NoError;
00487 }
00488 
00489 CameraC328::ErrorNumber CameraC328::sendSetPackageSize(uint16_t packageSize) {
00490     char send[COMMAND_LENGTH];
00491     send[0] = 0xAA;
00492     send[1] = 0x06;
00493     send[2] = 0x08;
00494     send[3] = (packageSize >> 0) & 0xff;
00495     send[4] = (packageSize >> 8) & 0xff;
00496     send[5] = 0x00;
00497 
00498     if (!SENDFUNC(send, sizeof(send))) {
00499         return (ErrorNumber)SendRegisterTimeout;
00500     }
00501     return (ErrorNumber)NoError;
00502 }
00503 
00504 CameraC328::ErrorNumber CameraC328::sendSetBaudrate(Baud baud) {
00505     char send[COMMAND_LENGTH];
00506 
00507     static struct baud_list {
00508         Baud baud;
00509         uint8_t div1st;
00510         uint8_t div2nd;
00511     } baudtable [] = {
00512         { Baud7200, 0xff, 0x01 },
00513         { Baud9600, 0xbf, 0x01 },
00514         { Baud14400, 0x7f, 0x01 },
00515         { Baud19200, 0x5f, 0x01 },
00516         { Baud28800, 0x3f, 0x01 },
00517         { Baud38400, 0x2f, 0x01 },
00518         { Baud57600, 0x1f, 0x01 },
00519         { Baud115200, 0x0f, 0x01 }
00520     };
00521 
00522     uint8_t div1st = 0x00, div2nd = 0x00;
00523     struct baud_list *p = &baudtable[0];
00524     for (int i = 0; i < sizeof(baudtable) / sizeof(baudtable[0]); i++) {
00525         if (p->baud == baud) {
00526             div1st = p->div1st;
00527             div2nd = p->div2nd;
00528         }
00529         p++;
00530     }
00531 
00532     send[0] = 0xAA;
00533     send[1] = 0x07;
00534     send[2] = div1st;
00535     send[3] = div2nd;
00536     send[4] = 0x00;
00537     send[5] = 0x00;
00538 
00539     if (!SENDFUNC(send, sizeof(send))) {
00540         return (ErrorNumber)SendRegisterTimeout;
00541     }
00542 
00543     return (ErrorNumber)NoError;
00544 }
00545 
00546 CameraC328::ErrorNumber CameraC328::sendReset(ResetType rt, bool specialReset) {
00547     char send[COMMAND_LENGTH];
00548     send[0] = 0xAA;
00549     send[1] = 0x08;
00550     send[2] = (int)rt;
00551     send[3] = 0x00;
00552     send[4] = 0x00;
00553     send[5] = specialReset ? 0xff : 0x00;
00554     /*
00555      * Special reset : If the parameter is 0xFF, the command is a special Reset command and the firmware responds to it immediately.
00556      */
00557 
00558     if (!SENDFUNC(send, sizeof(send))) {
00559         return (ErrorNumber)SendRegisterTimeout;
00560     }
00561 
00562     return (ErrorNumber)NoError;
00563 }
00564 
00565 CameraC328::ErrorNumber CameraC328::sendPowerOff() {
00566     char send[COMMAND_LENGTH];
00567     send[0] = 0xAA;
00568     send[1] = 0x09;
00569     send[2] = 0x00;
00570     send[3] = 0x00;
00571     send[4] = 0x00;
00572     send[5] = 0x00;
00573 
00574     if (!SENDFUNC(send, sizeof(send))) {
00575         return (ErrorNumber)SendRegisterTimeout;
00576     }
00577 
00578     return (ErrorNumber)NoError;
00579 }
00580 
00581 CameraC328::ErrorNumber CameraC328::recvData(DataType *dt, uint32_t *length) {
00582     char recv[COMMAND_LENGTH];
00583     if (!RECVFUNC(recv, sizeof(recv))) {
00584         return (ErrorNumber)UnexpectedReply;
00585     }
00586     if ((0xAA != recv[0]) || (0x0A != recv[1])) {
00587         return (ErrorNumber)UnexpectedReply;
00588     }
00589     *dt = (DataType)recv[2];
00590     *length = (recv[5] << 16) | (recv[4] << 8) | (recv[3] << 0);
00591     return (ErrorNumber)NoError;
00592 }
00593 
00594 CameraC328::ErrorNumber CameraC328::sendSync() {
00595     char send[COMMAND_LENGTH];
00596     send[0] = 0xAA;
00597     send[1] = 0x0D;
00598     send[2] = 0x00;
00599     send[3] = 0x00;
00600     send[4] = 0x00;
00601     send[5] = 0x00;
00602     if (!SENDFUNC(send, sizeof(send))) {
00603         return (ErrorNumber)SendRegisterTimeout;
00604     }
00605     return (ErrorNumber)NoError;
00606 }
00607 
00608 CameraC328::ErrorNumber CameraC328::recvSync() {
00609     char recv[COMMAND_LENGTH];
00610     if (!RECVFUNC(recv, sizeof(recv))) {
00611         return (ErrorNumber)UnexpectedReply;
00612     }
00613     if ((0xAA != recv[0]) || (0x0D != recv[1])) {
00614         return (ErrorNumber)UnexpectedReply;
00615     }
00616     return (ErrorNumber)NoError;
00617 }
00618 
00619 /**
00620  * Send ACK.
00621  *
00622  * @param commandId The command with that ID is acknowledged by this command.
00623  * @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.
00624  */
00625 CameraC328::ErrorNumber CameraC328::sendAck(uint8_t commandId, uint16_t packageId) {
00626     char send[COMMAND_LENGTH];
00627     send[0] = 0xAA;
00628     send[1] = 0x0E;
00629     send[2] = commandId;
00630     send[3] = 0x00;    // ACK counter is not used.
00631     send[4] = (packageId >> 0) & 0xff;
00632     send[5] = (packageId >> 8) & 0xff;
00633     if (!SENDFUNC(send, sizeof(send))) {
00634         return (ErrorNumber)SendRegisterTimeout;
00635     }
00636     return (ErrorNumber)NoError;
00637 }
00638 
00639 /**
00640  * Receive ACK or NCK.
00641  *
00642  * @return Error number.
00643  */
00644 CameraC328::ErrorNumber CameraC328::recvAckOrNck() {
00645     char recv[COMMAND_LENGTH];
00646     if (!RECVFUNC(recv, sizeof(recv))) {
00647         return (ErrorNumber)UnexpectedReply;
00648     }
00649     if ((0xAA == recv[0]) && (0x0E == recv[1])) {
00650         return (ErrorNumber)NoError;
00651     }
00652     if ((0xAA == recv[0]) && (0x0F == recv[1])) {
00653         return (ErrorNumber)recv[4];
00654     }
00655     return (ErrorNumber)UnexpectedReply;
00656 }
00657 
00658 /**
00659  * Send bytes to camera module.
00660  *
00661  * @param buf Pointer to the data buffer.
00662  * @param len Length of the data buffer.
00663  *
00664  * @return True if the data sended.
00665  */
00666 bool CameraC328::sendBytes(char *buf, size_t len, int timeout_us) {
00667     for (uint32_t i = 0; i < (uint32_t)len; i++) {
00668         int cnt = 0;
00669         while (!serial.writeable()) {
00670             wait_us(1);
00671             cnt++;
00672             if (timeout_us < cnt) {
00673                 return false;
00674             }
00675         }
00676         serial.putc(buf[i]);
00677     }
00678     return true;
00679 }
00680 
00681 /**
00682  * Receive bytes from camera module.
00683  *
00684  * @param buf Pointer to the data buffer.
00685  * @param len Length of the data buffer.
00686  *
00687  * @return True if the data received.
00688  */
00689 bool CameraC328::recvBytes(char *buf, size_t len, int timeout_us) {
00690     for (uint32_t i = 0; i < (uint32_t)len; i++) {
00691         int cnt = 0;
00692         while (!serial.readable()) {
00693             wait_us(1);
00694             cnt++;
00695             if (timeout_us < cnt) {
00696                 return false;
00697             }
00698         }
00699         buf[i] = serial.getc();
00700     }
00701     return true;
00702 }
00703 
00704 /**
00705  * Wait received.
00706  *
00707  * @return True if the data received.
00708  */
00709 bool CameraC328::waitRecv() {
00710     while (!serial.readable()) {
00711     }
00712     return true;
00713 }
00714 
00715 /**
00716  * Wait idle state.
00717  */
00718 bool CameraC328::waitIdle() {
00719     while (serial.readable()) {
00720         serial.getc();
00721     }
00722     return true;
00723 }