Tadao Iida / Mbed 2 deprecated miconcarctrl

Dependencies:   TextLCD mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CameraC1098.cpp Source File

CameraC1098.cpp

00001 /**
00002  * C1098-SS device driver class (Version 1.0)
00003  * Reference documents: C1098-SS User Manual v1.0 2012.4.1
00004  *
00005  * CameraC328Library
00006  * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
00007  * http://shinta.main.jp/
00008  *
00009  * CameraC1098-SS Library
00010  * Copyright (C) 2012 Tadao Iida
00011  */
00012 
00013 #include "CameraC1098.h"
00014 
00015 #define WAITIDLE    waitIdle
00016 #define SENDFUNC    sendBytes
00017 #define RECVFUNC    recvBytes
00018 #define WAITFUNC    waitRecv
00019 
00020 /**
00021  * Constructor.
00022  *
00023  * @param tx A pin for transmit.
00024  * @param rx A pin for receive.
00025  * @param baud Baud rate. (Default is Baud14400.)
00026  */
00027 CameraC1098::CameraC1098(PinName tx, PinName rx, int baud) : serial(tx, rx) {
00028     serial.baud(baud);
00029 }
00030 
00031 /**
00032  * Destructor.
00033  */
00034 CameraC1098::~CameraC1098() {
00035 }
00036 
00037 /**
00038  * Make a sync. for baud rate.
00039  */
00040 CameraC1098::ErrorNumber CameraC1098::sync() {
00041     for (int i = 0; i < SYNCMAX; i++) {
00042         if (NoError == sendSync()) {
00043             if (NoError == recvAckOrNck()) {
00044                 if (NoError == recvSync()) {
00045                     if (NoError == sendAck(0x0D, 0x00)) {
00046                         /*
00047                          * After synchronization, the camera needs a little time for AEC and AGC to be stable.
00048                          * Users should wait for 1-2 seconds before capturing the first picture.
00049                          */
00050                         wait(2.0);
00051                         return NoError;
00052                     }
00053                 }
00054             }
00055         }
00056         wait_ms(50);
00057     }
00058     return UnexpectedReply;
00059 }
00060 
00061 /**
00062  * Initialize.
00063  *
00064  * @param baud Camera Interface Speed.
00065  * @param jr JPEG resolution.
00066  */
00067 CameraC1098::ErrorNumber CameraC1098::init(Baud baud,JpegResolution jr) {
00068     int i ;
00069     ErrorNumber en;
00070     WAITIDLE();
00071     setmbedBaud((Baud)(0x07)) ;
00072   
00073     for ( i = 1 ; i < 7 ; i++ ) {
00074         if ( NoError == sendSync() ) {
00075             if ( NoError == recvAckOrNck() ){
00076                 if ( NoError == recvSync() ) {
00077                     if ( NoError == sendAck(0x0D, 0x00) ) {
00078                         en = sendInitial(baud,jr);
00079                         if (NoError != en) {
00080                             return en;
00081                         }    
00082                         en = recvAckOrNck();
00083                         if (NoError != en) {
00084                             return en;
00085                         }      
00086                         wait_ms(50) ;
00087                         setmbedBaud(baud);   
00088                         //wait_ms(50) ; 
00089                         static bool alreadySetupPackageSize = false;
00090                         if (!alreadySetupPackageSize) {
00091                             en = sendSetPackageSize(packageSize);
00092                             if (NoError != en) {
00093                                 return en;
00094                             }
00095                             WAITFUNC();
00096                             en = recvAckOrNck();
00097                             if (NoError != en) {
00098                                 return en;
00099                             }
00100                             alreadySetupPackageSize = true;
00101                         }
00102                         
00103                         wait(2.0);
00104                         return (ErrorNumber)NoError;                                                                 
00105                        /*
00106                         * After synchronization, the camera needs a little time for AEC and AGC to be stable.
00107                         * Users should wait for 1-2 seconds before capturing the first picture.
00108                         */
00109                     }
00110                 }                 
00111             }else{
00112                 setmbedBaud((Baud)(i+1)) ;   
00113             }
00114         }
00115         wait_ms(50);   
00116     }                 
00117     return UnexpectedReply;
00118 }
00119 
00120 
00121 /**
00122  * Get JPEG snapshot picture.
00123  *
00124  * @param func A pointer to a callback function.
00125  *             You can block this function until saving the image datas.
00126  * @return Status of the error.
00127  */
00128 CameraC1098::ErrorNumber CameraC1098::getJpegSnapshotPicture(void(*func)(char *buf, size_t siz)) {
00129     WAITIDLE();
00130     ErrorNumber en;
00131 
00132 
00133     en = sendSnapshot();
00134     if (NoError != en) {
00135         return en;
00136     }
00137     WAITFUNC();
00138     en = recvAckOrNck();
00139     if (NoError != en) {
00140         return en;
00141     }
00142 
00143     en = sendGetPicture();
00144     if (NoError != en) {
00145         return en;
00146     }
00147     WAITFUNC();
00148     en = recvAckOrNck();
00149     if (NoError != en) {
00150         return en;
00151     }
00152 
00153     /*
00154      * Data : snapshot picture
00155      */
00156     uint32_t length = 0;
00157     WAITFUNC();
00158     en = recvData(&length);
00159     if (NoError != en) {
00160         return en;
00161     }
00162     en = sendAck(0x00, 0);
00163     if (NoError != en) {
00164         return en;
00165     }
00166 
00167     char databuf[packageSize - 6];
00168     uint16_t pkg_total = length / (packageSize - 6);
00169     for (int i = 0; i <= (int)pkg_total; i++) {
00170         uint16_t checksum = 0;
00171         // ID.
00172         char idbuf[2];
00173         WAITFUNC();
00174         if (!RECVFUNC(idbuf, sizeof(idbuf))) {
00175             return (ErrorNumber)UnexpectedReply;
00176         }
00177         checksum += idbuf[0];
00178         checksum += idbuf[1];
00179         uint16_t id = (idbuf[1] << 8) | (idbuf[0] << 0);
00180         if (id != i) {
00181             return (ErrorNumber)UnexpectedReply;
00182         }
00183 
00184         // Size of the data.
00185         char dsbuf[2];
00186         WAITFUNC();
00187         if (!RECVFUNC(dsbuf, sizeof(dsbuf))) {
00188             return (ErrorNumber)UnexpectedReply;
00189         }
00190 
00191         // Received the data.
00192         checksum += dsbuf[0];
00193         checksum += dsbuf[1];
00194         uint16_t ds = (dsbuf[1] << 8) | (dsbuf[0] << 0);
00195         WAITFUNC();
00196         if (!RECVFUNC(&databuf[0], ds)) {
00197             return (ErrorNumber)UnexpectedReply;
00198         }
00199         for (int j = 0; j < ds; j++) {
00200             checksum += databuf[j];
00201         }
00202 
00203         // Verify code.
00204         char vcbuf[2];
00205         WAITFUNC();
00206         if (!RECVFUNC(vcbuf, sizeof(vcbuf))) {
00207             return (ErrorNumber)UnexpectedReply;
00208         }
00209         uint16_t vc = (vcbuf[1] << 8) | (vcbuf[0] << 0);
00210         if (vc != (checksum & 0xff)) {
00211             return (ErrorNumber)UnexpectedReply;
00212         }
00213 
00214         /*
00215          * Call a call back function.
00216          * You can block this function while working.
00217          */
00218         func(databuf, ds);
00219 
00220         /*
00221          * We should wait for camera working before reply a ACK.
00222          */
00223         wait_ms(100);
00224         en = sendAck(0x00, 1 + i);
00225         if (NoError != en) {
00226             return en;
00227         }
00228     }
00229 
00230     return (ErrorNumber)NoError;
00231 }
00232 
00233 
00234 
00235 CameraC1098::ErrorNumber CameraC1098::sendInitial(Baud baud, JpegResolution jr) {
00236     char send[COMMAND_LENGTH];
00237     
00238     send[0] = 0xAA;
00239     send[1] = 0x01;
00240     send[2] = (char)baud;
00241     send[3] = 0x07;
00242     send[4] = 0x00;
00243     send[5] = (char)jr;
00244 
00245     if (!SENDFUNC(send, sizeof(send))) {
00246         return (ErrorNumber)SendRegisterTimeout;
00247     }
00248 
00249     return (ErrorNumber)NoError;
00250 }
00251 
00252 CameraC1098::ErrorNumber CameraC1098::sendGetPicture(void) {
00253     char send[COMMAND_LENGTH];
00254 
00255     send[0] = 0xAA;
00256     send[1] = 0x04;
00257     send[2] = 0x01;
00258     send[3] = 0x00;
00259     send[4] = 0x00;
00260     send[5] = 0x00;
00261 
00262     if (!SENDFUNC(send, sizeof(send))) {
00263         return (ErrorNumber)SendRegisterTimeout;
00264     }
00265     return (ErrorNumber)NoError;
00266 }
00267 
00268 CameraC1098::ErrorNumber CameraC1098::sendSnapshot(void) {
00269     char send[COMMAND_LENGTH];
00270     send[0] = 0xAA;
00271     send[1] = 0x05;
00272     send[2] = 0x00;
00273     send[3] = 0x00;
00274     send[4] = 0x00;
00275     send[5] = 0x00;
00276 
00277     if (!SENDFUNC(send, sizeof(send))) {
00278         return (ErrorNumber)SendRegisterTimeout;
00279     }
00280     return (ErrorNumber)NoError;
00281 }
00282 
00283 CameraC1098::ErrorNumber CameraC1098::sendSetPackageSize(uint16_t packageSize) {
00284     char send[COMMAND_LENGTH];
00285     send[0] = 0xAA;
00286     send[1] = 0x06;
00287     send[2] = 0x08;
00288     send[3] = (packageSize >> 0) & 0xff;
00289     send[4] = (packageSize >> 8) & 0xff;
00290     send[5] = 0x00;
00291 
00292     if (!SENDFUNC(send, sizeof(send))) {
00293         return (ErrorNumber)SendRegisterTimeout;
00294     }
00295     return (ErrorNumber)NoError;
00296 }
00297 
00298 void CameraC1098::setmbedBaud(Baud baud){
00299     switch((int)baud){
00300     case 2:
00301         serial._baud(460800);
00302         break;
00303     case 3:
00304         serial._baud(230400);
00305         break;
00306     case 4:
00307         serial._baud(115200);
00308         break;
00309     case 5:
00310         serial._baud(57600);
00311         break;
00312     case 6:
00313         serial._baud((int)28800);
00314         break;
00315     case 7:
00316         serial._baud(14400);
00317         break;    
00318     default:
00319         serial._baud(14400);  
00320     }
00321 }
00322 
00323 
00324 CameraC1098::ErrorNumber CameraC1098::sendReset(ResetType specialReset) {
00325     char send[COMMAND_LENGTH];
00326     send[0] = 0xAA;
00327     send[1] = 0x08;
00328     send[2] = 0x00;
00329     send[3] = 0x00;
00330     send[4] = 0x00;
00331     send[5] = specialReset;
00332     /*
00333      * Special reset : If the parameter is 0xFF, the command is a special Reset command and the firmware responds to it immediately.
00334      */
00335 
00336     if (!SENDFUNC(send, sizeof(send))) {
00337         return (ErrorNumber)SendRegisterTimeout;
00338     }
00339 
00340     return (ErrorNumber)NoError;
00341 }
00342 
00343 
00344 CameraC1098::ErrorNumber CameraC1098::recvData(uint32_t *length) {
00345     char recv[COMMAND_LENGTH];
00346     if (!RECVFUNC(recv, sizeof(recv))) {
00347         return (ErrorNumber)UnexpectedReply;
00348     }
00349     if ((0xAA != recv[0]) || (0x0A != recv[1])) {
00350         return (ErrorNumber)UnexpectedReply;
00351     }
00352     recv[2] = (char)0x01;
00353     *length = (recv[5] << 16) | (recv[4] << 8) | (recv[3] << 0);
00354     return (ErrorNumber)NoError;
00355 }
00356 
00357 CameraC1098::ErrorNumber CameraC1098::sendSync() {
00358     char send[COMMAND_LENGTH];
00359     send[0] = 0xAA;
00360     send[1] = 0x0D;
00361     send[2] = 0x00;
00362     send[3] = 0x00;
00363     send[4] = 0x00;
00364     send[5] = 0x00;
00365     
00366     
00367     if (!SENDFUNC(send, sizeof(send))) {
00368         return (ErrorNumber)SendRegisterTimeout;
00369     }
00370     return (ErrorNumber)NoError;
00371 }
00372 
00373 CameraC1098::ErrorNumber CameraC1098::recvSync() {
00374     char recv[COMMAND_LENGTH];
00375     
00376     if (!RECVFUNC(recv, sizeof(recv))) {
00377         return (ErrorNumber)UnexpectedReply;
00378     }
00379     if ((0xAA != recv[0]) || (0x0D != recv[1])) {
00380         return (ErrorNumber)UnexpectedReply;
00381     }
00382     return (ErrorNumber)NoError;
00383 }
00384 
00385 /**
00386  * Send ACK.
00387  *
00388  * @param commandId The command with that ID is acknowledged by this command.
00389  * @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.
00390  */
00391 CameraC1098::ErrorNumber CameraC1098::sendAck(uint8_t commandId, uint16_t packageId) {
00392     char send[COMMAND_LENGTH];
00393 
00394     send[0] = 0xAA;
00395     send[1] = 0x0E;
00396     send[2] = commandId;
00397     send[3] = 0x00;    // ACK counter is not used.
00398     send[4] = (packageId >> 0) & 0xff;
00399     send[5] = (packageId >> 8) & 0xff;
00400     if (!SENDFUNC(send, sizeof(send))) {
00401         return (ErrorNumber)SendRegisterTimeout;
00402     }
00403     return (ErrorNumber)NoError;
00404 }
00405 
00406 /**
00407  * Receive ACK or NCK.
00408  *
00409  * @return Error number.
00410  */
00411 CameraC1098::ErrorNumber CameraC1098::recvAckOrNck() {
00412     char recv[COMMAND_LENGTH];
00413         
00414     if (!RECVFUNC(recv, sizeof(recv))) {
00415         return (ErrorNumber)UnexpectedReply;
00416     }
00417     if ((0xAA == recv[0]) && (0x0E == recv[1])) {
00418         return (ErrorNumber)NoError;
00419     }
00420     if ((0xAA == recv[0]) && (0x0F == recv[1]) && (0x00 == recv[2])) {
00421         return (ErrorNumber)NoError;
00422     }    
00423     if ((0xAA == recv[0]) && (0x0F == recv[1])) {
00424         return (ErrorNumber)recv[4];
00425     }
00426     return (ErrorNumber)UnexpectedReply;
00427 }
00428 
00429 /**
00430  * Send bytes to camera module.
00431  *
00432  * @param buf Pointer to the data buffer.
00433  * @param len Length of the data buffer.
00434  *
00435  * @return True if the data sended.
00436  */
00437 bool CameraC1098::sendBytes(char *buf, size_t len, int timeout_us) {
00438     for (uint32_t i = 0; i < (uint32_t)len; i++) {
00439         int cnt = 0;
00440         while (!serial.writeable()) {
00441             wait_us(1);
00442             cnt++;
00443             if (timeout_us < cnt) {
00444                 return false;
00445             }
00446         }
00447         serial.putc(buf[i]);
00448     }
00449     return true;
00450 }
00451 
00452 /**
00453  * Receive bytes from camera module.
00454  *
00455  * @param buf Pointer to the data buffer.
00456  * @param len Length of the data buffer.
00457  *
00458  * @return True if the data received.
00459  */
00460 bool CameraC1098::recvBytes(char *buf, size_t len, int timeout_us) {
00461     for (uint32_t i = 0; i < (uint32_t)len; i++) {
00462         int cnt = 0;
00463         while (!serial.readable()) {
00464             wait_us(1);
00465             cnt++;
00466             if (timeout_us < cnt) {
00467                 return false;
00468             }
00469         }
00470         buf[i] = serial.getc();
00471     }
00472     return true;
00473 }
00474 
00475 /**
00476  * Wait received.
00477  *
00478  * @return True if the data received.
00479  */
00480 bool CameraC1098::waitRecv() {
00481     while (!serial.readable()) {
00482     }
00483     return true;
00484 }
00485 
00486 /**
00487  * Wait idle state.
00488  */
00489 bool CameraC1098::waitIdle() {
00490     while (serial.readable()) {
00491         serial.getc();
00492     }
00493     return true;
00494 }