Library for LinkSprite Y201 JPEG serial camera.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Y201.cpp Source File

Y201.cpp

00001 #include "Y201.h"
00002 #include "rtos.h"
00003 
00004 const char Y201::resetSeq            [4] = {0x56,0x00,0x26,0x00};
00005 const char Y201::resetSeqAck         [4] = {0x76,0x00,0x26,0x00};
00006 const char Y201::takePicSeq          [5] = {0x56,0x00,0x36,0x01,0x00};
00007 const char Y201::takePicSeqAck       [5] = {0x76,0x00,0x36,0x00,0x00};
00008 const char Y201::set160x120          [9] = {0x56,0x00,0x31,0x05,0x04,0x01,0x00,0x19,0x22};
00009 const char Y201::set320x240          [9] = {0x56,0x00,0x31,0x05,0x04,0x01,0x00,0x19,0x11};
00010 const char Y201::set640x480          [9] = {0x56,0x00,0x31,0x05,0x04,0x01,0x00,0x19,0x00};
00011 const char Y201::setSizeAck          [5] = {0x76,0x00,0x31,0x00,0x00};
00012 const char Y201::readFileSize        [5] = {0x56,0x00,0x34,0x01,0x00};
00013 const char Y201::readFileSizeAck     [7] = {0x76,0x00,0x34,0x00,0x04,0x00,0x00};
00014 const char Y201::readFileHead        [8] = {0x56,0x00,0x32,0x0C,0x00,0x0A,0x00,0x00};
00015 const char Y201::readFileAck         [5] = {0x76,0x00,0x32,0x00,0x00};
00016 //const char Y201::changeBaudRateSeq   [5] = {0x56,0x00,0x24,0x03,0x01};
00017 //const char Y201::changeBaudRateAck   [5] = {0x76,0x00,0x24,0x00,0x00};
00018 const char Y201::enterPowerSavingSeq [7] = {0x56,0x00,0x3E,0x03,0x00,0x01,0x01};
00019 const char Y201::enterPowerSavingAck [5] = {0x76,0x00,0x3E,0x00,0x00};
00020 const char Y201::exitPowerSavingSeq  [7] = {0x56,0x00,0x3E,0x03,0x00,0x01,0x00};
00021 const char Y201::exitPowerSavingAck  [5] = {0x76,0x00,0x3E,0x00,0x00};
00022 
00023 void Y201::trash() {
00024     // wait for trash...
00025     while(readable()) {
00026         int x = getc();
00027     }
00028 }
00029 
00030 bool Y201::readImage(int startAddress, int readLen, uint8_t *readBuffer) {
00031    trash(); // camera sends random crap after sending certain responses, so need to clear it
00032    //Thread::wait(5);
00033    putSeq(readFileHead,readFileHeadLen);
00034    putc(startAddress>>8); // Start Address MSB
00035    putc(startAddress&255); // Start Address LSB
00036    putc(0x00);
00037    putc(0x00);
00038    putc(readLen>>8); // Length of file MSB
00039    putc(readLen&255); // length of file LSB
00040    putc(0x00); // Interval MSB
00041    putc(0x0A); // Interval LSB
00042    int nread = 0;
00043    if(waitFor(readFileAck,readFileAckLen)) {
00044       Thread::wait(1);
00045       Timer t;
00046       t.start();
00047       while(nread<readLen) {
00048          if(readable()) {
00049             uint8_t c = getc();
00050             // fprintf(stdout, "[%02x]", c);
00051             readBuffer[nread] = c;
00052             nread++;
00053             t.reset();
00054          } else {
00055             if(t.read_ms()>3000) {
00056                fprintf(stdout, "Blocked!\n Missed %d bytes over %d\nLast byte read is %02x\n", readLen - nread, readLen, readBuffer[nread-1]);
00057                return false;
00058             }
00059          }
00060      }
00061      Thread::wait(1);
00062    } else {
00063       return false;
00064    }
00065    return true;
00066 }
00067 
00068 bool Y201::waitFor(const char *seq, const int seqLen) {
00069     int spos = 0;
00070     long timeout = 100;
00071     Timer timer;
00072     timer.start();
00073     while(spos<seqLen) {
00074         if(readable()) {
00075             int c = getc();
00076             if(seq[spos]==c) {
00077                 spos++;
00078             } else {
00079                 return false;
00080             }
00081         } else {
00082             if(timer.read_ms()>timeout) {
00083                 return false;
00084             }
00085         }
00086     }
00087     return true;
00088 }
00089 
00090 bool Y201::waitForInt(int bytes, int *fileSize) {
00091    int spos = 0;
00092    long timeout = 100;
00093    Timer timer;
00094    timer.start();
00095    *fileSize = 0;
00096    while(spos<bytes) {
00097         if(readable()) {
00098             uint8_t val = getc();
00099             if(spos==0) {
00100                 *fileSize += (val<<8);
00101             } else {
00102                 *fileSize += val;
00103             }
00104             
00105             spos++;
00106             
00107         } else {
00108             if(timer.read_ms()>timeout) {
00109                 return false;
00110             }
00111         }
00112     }
00113     return true;
00114 }
00115 
00116 void Y201::putSeq(const char *seq, int seqLen) {
00117     while(seqLen--) {
00118         putc(*seq++);
00119     }
00120 }
00121 
00122 Y201::Y201(PinName tx, PinName rx, const char *name) : MODSERIAL(tx,rx,name) {
00123     baud(38400);
00124 }
00125 
00126 bool Y201::setImageSize(Y201ImageSize size) {
00127     switch(size) {
00128         case Y201::e640x480:
00129             putSeq(set640x480,setSizeLen);
00130         break;
00131         
00132         case Y201::e160x120:
00133             putSeq(set160x120,setSizeLen);
00134         break;
00135         
00136         case Y201::e320x240:
00137             putSeq(set320x240,setSizeLen);
00138         break;
00139     }
00140     return waitFor(setSizeAck,setSizeAckLen);
00141 }
00142 
00143 bool Y201::takePicture() {
00144    putSeq(takePicSeq,takePicSeqLen);
00145    Thread::wait(50);
00146    return waitFor(takePicSeqAck,takePicSeqAckLen);
00147 }
00148 
00149 bool Y201::enterPowerSaving() {
00150     putSeq(enterPowerSavingSeq,enterPowerSavingLen);
00151     return waitFor(enterPowerSavingAck,enterPowerSavingAckLen);
00152 }
00153 
00154 bool Y201::exitPowerSaving() {
00155     putSeq(exitPowerSavingSeq,exitPowerSavingLen);
00156     return waitFor(exitPowerSavingAck,exitPowerSavingAckLen);
00157 }
00158 
00159 bool Y201::readImageSize(int *fileSize) {
00160    putSeq(readFileSize,readFileSizeLen);
00161    bool ret = waitFor(readFileSizeAck,readFileSizeAckLen);
00162    if(!ret)
00163       return false;
00164   return waitForInt(2,fileSize);
00165 }
00166 
00167 bool Y201::reset() {
00168   putSeq(resetSeq,resetSeqLen);
00169   bool ret = waitFor(resetSeqAck,resetSeqAckLen);
00170 
00171   // wait for trash
00172   int count = 3;
00173   while(count) {
00174     count--;
00175     if(readable()) {
00176         while(readable()) {
00177             int c = getc();
00178         }
00179     }
00180     Thread::wait(1000);
00181   }
00182   return ret;
00183 }
00184 
00185 /*
00186 
00187 THIS SIMPLY DOESN'T WORK -- Known bug, LinkSprite quality products
00188 
00189 
00190 bool Y201::changeBaudRate(Y201BaudRate baudRate) {
00191    // put the prefix
00192    putSeq(changeBaudRateSeq,changeBaudRateSeqLen);
00193    int br = 9600;
00194    
00195    // put the baud rate
00196    switch(baudRate) {
00197       case Y201::e9600:
00198          putc(0xAE);
00199          putc(0xC8);
00200          br = 9600;
00201       break;
00202       
00203       case Y201::e19200:
00204          putc(0x56);
00205          putc(0xE4);
00206          br = 19200;
00207       break;
00208       
00209       case Y201::e38400:
00210          putc(0x2A);
00211          putc(0xF2);
00212          br = 38400;
00213       break;
00214       
00215       case Y201::e57600:
00216          putc(0x1C);
00217          putc(0x4C);
00218          br = 57600;
00219       break;
00220       
00221       case Y201::e115200:
00222          putc(0xAE);
00223          putc(0xC8);
00224          br = 115200;
00225       break;
00226       
00227       default:
00228          putc(0xAE);
00229          putc(0xC8);
00230          br = 9600;
00231       break;
00232    }
00233    
00234    baud(br);
00235    
00236    // wait for the ack
00237    return waitFor(changeBaudRateAck,changeBaudRateAckLen);
00238 }
00239 */