fork of Camera_LS_Y201 lib supporting the 2MP variant/successor
Fork of Camera_LS_Y201 by
Camera_LS_Y201.cpp
- Committer:
- humlet
- Date:
- 2014-03-18
- Revision:
- 2:ce4d1351bdeb
- Parent:
- 1:43358d40f879
File content as of revision 2:ce4d1351bdeb:
/** * ============================================================================= * LS-Y201 device driver class (Version 0.0.1) * Reference documents: LinkSprite JPEG Color Camera Serial UART Interface * January 2010 * ============================================================================= * Copyright (c) 2010 Shinichiro Nakamura (CuBeatSystems) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * ============================================================================= */ #include "Camera_LS_Y201.h" #define TMOUT 2000 /** * Create. * * @param tx Transmitter. * @param rx Receiver. */ Camera_LS_Y201::Camera_LS_Y201(PinName tx, PinName rx) : serial(tx, rx) { serial.baud(115200); } /** * Dispose. */ Camera_LS_Y201::~Camera_LS_Y201() { } /** * Reset module. * * @return Error code. */ Camera_LS_Y201::ErrorCode Camera_LS_Y201::reset() { uint8_t send[4] = { 0x56, 0x00, 0x26, 0x00 }; //uint8_t recv[50]; const int nBauds = 5; const int bauds[nBauds] = {38400,57600,115200,128000,256000}; for(int i=0; i<nBauds; ++i) { printf("Reset @ %d baud: ",bauds[i]); serial.baud(bauds[i]); waitIdle(); if (!sendBytes(send, sizeof(send), 200 * TMOUT)) { printf("TxKO\n"); continue; } else { printf("TxOK "); } //serial.baud(115200); ErrorCode r = waitInitEnd(); if (r != NoError) { printf("RxKO\n"); continue; } else { printf("RxOK ...4s...\n"); wait(4); return NoError; } } return UnexpectedReply; /* if (!recvBytes(recv, sizeof(recv), 200 * TMOUT)) { return RecvError; } if ((recv[0] == 0x76) && (recv[1] == 0x00) && (recv[2] == 0x26) && (recv[3] == 0x00)) { ErrorCode r = waitInitEnd(); if (r != NoError) { return r; } wait(4); return NoError; } else { printf("%X %X %X %X\n",recv[0],recv[1],recv[2],recv[3]); return UnexpectedReply; } */ } /** * Set image size. * * @param is Image size. * @return Error code. */ Camera_LS_Y201::ErrorCode Camera_LS_Y201::setImageSize(ImageSize is) { uint8_t send[5] = { 0x56, 0x00, 0x54, 0x01, 0x00 // 0x11:320x240, 0x00:640x480, 0x22:160x120 }; uint8_t recv[5]; switch (is) { case ImageSize160x120: send[4] = 0x22; break; case ImageSize320x240: send[4] = 0x11; break; case ImageSize640x480: send[4] = 0x00; break; case ImageSize800x600: send[4] = 0x1d; break; case ImageSize1024x768: send[4] = 0x1c; break; case ImageSize1280x960: send[4] = 0x1b; break; case ImageSize1600x1200: send[4] = 0x21; break; default: return InvalidArguments; } if (!sendBytes(send, sizeof(send), 200 * TMOUT)) { return SendError; } if (!recvBytes(recv, sizeof(recv), 200 * TMOUT)) { return RecvError; } if ((recv[0] == 0x76) && (recv[1] == 0x00) && (recv[2] == 0x54) && (recv[3] == 0x00) && (recv[4] == 0x00)) { wait(1); //return reset(); return NoError; } else { return UnexpectedReply; } } Camera_LS_Y201::ErrorCode Camera_LS_Y201::setCompressionRatio(int cr) { uint8_t send[9] = { 0x56, 0x00, 0x31, 0x05, 0x01, 0x01, 0x12, 0x04, cr }; uint8_t recv[5]; //printf("Setting Img-Qual to %d\n", cr); if (!sendBytes(send, sizeof(send), 200 * TMOUT)) { return SendError; } if (!recvBytes(recv, sizeof(recv), 200 * TMOUT)) { return RecvError; } if ((recv[0] == 0x76) && (recv[1] == 0x00) && (recv[2] == 0x31) && (recv[3] == 0x00) && (recv[4] == 0x00)) { wait(1); //return reset(); return NoError; } else { return UnexpectedReply; } } Camera_LS_Y201::ErrorCode Camera_LS_Y201::setBaudRate(Camera_LS_Y201::BaudRate br) { uint8_t send[6] = { 0x56, 0x00, 0x24, 0x03, 0x01, br }; uint8_t recv[5]; if (!sendBytes(send, sizeof(send), 200 * TMOUT)) { return SendError; } if (!recvBytes(recv, sizeof(recv), 200 * TMOUT)) { return RecvError; } if ((recv[0] == 0x76) && (recv[1] == 0x00) && (recv[2] == 0x24) && (recv[3] == 0x00) && (recv[4] == 0x00)) { wait(1); //return reset(); switch(br) { /*case BaudRate9600: serial.baud(9600); break;*/ case BaudRate38400: serial.baud(38400); break; case BaudRate57600: serial.baud(57600); break; case BaudRate115200: serial.baud(115200); break; case BaudRate128000: serial.baud(128000); break; case BaudRate256000: serial.baud(256000); break; default: return InvalidArguments; } return NoError; } else { return UnexpectedReply; } } /** * Take picture. * * @return Error code. */ Camera_LS_Y201::ErrorCode Camera_LS_Y201::takePicture() { uint8_t send[5] = { 0x56, 0x00, 0x36, 0x01, 0x00 }; uint8_t recv[5]; if (!sendBytes(send, sizeof(send), 200 * TMOUT)) { return SendError; } if (!recvBytes(recv, sizeof(recv), 2000 * TMOUT)) { return RecvError; } if ((recv[0] == 0x76) && (recv[1] == 0x00) && (recv[2] == 0x36) && (recv[3] == 0x00) && (recv[4] == 0x00)) { /* * I think the camera need a time for operating. * But there is no any comments on the documents. */ wait_ms(100); return NoError; } else { return UnexpectedReply; } } /** * Read jpeg file size. * * @param fileSize File size. * @return Error code. */ Camera_LS_Y201::ErrorCode Camera_LS_Y201::readJpegFileSize(int *fileSize) { uint8_t send[5] = { 0x56, 0x00, 0x34, 0x01, 0x00 }; uint8_t recv[9]; if (!sendBytes(send, sizeof(send), 2000 * TMOUT)) { return SendError; } if (!recvBytes(recv, sizeof(recv), 2000 * TMOUT)) { return RecvError; } if ((recv[0] == 0x76) && (recv[1] == 0x00) && (recv[2] == 0x34) && (recv[3] == 0x00) && (recv[4] == 0x04) && (recv[5] == 0x00) /*&& (recv[6] == 0x00)*/) { *fileSize = ((recv[6] & 0x00ff) << 16) | ((recv[7] & 0x00ff) << 8) | ((recv[8] & 0x00ff) << 0); return NoError; } else { return UnexpectedReply; } } /** * Read jpeg file content. * * @param func A pointer to a call back function. * @return Error code. */ Camera_LS_Y201::ErrorCode Camera_LS_Y201::readJpegFileContent(void (*func)(int done, int total, uint8_t *buf, size_t siz)) { uint8_t send[16] = { 0x56, 0x00, 0x32, 0x0C, 0x00, 0x0A, 0x00, 0x00, // 7 mhh 0x00, // 8 MH 0x00, // 9 ML 0x00, 0x00, // 11 khh 0x00, // 12 KH 0x00, // 13 KL 0x00, // XX 0x00 // XX }; uint8_t body[256]; uint32_t m = 0; // Staring address. uint32_t k = sizeof(body); // Packet size. uint16_t x = 10; // Interval time. XX XX * 0.01m[sec] bool end = false; /* * Get the data size. */ int siz_done = 0; int siz_total = 0; ErrorCode r = readJpegFileSize(&siz_total); if (r != NoError) { printf("ouch01\n"); return r; } printf("Going to read %d bytes\n", siz_total); do { send[7] = (m >> 16) & 0xff; send[8] = (m >> 8) & 0xff; send[9] = (m >> 0) & 0xff; send[11] = (k >> 16) & 0xff; send[12] = (k >> 8) & 0xff; send[13] = (k >> 0) & 0xff; send[14] = (x >> 8) & 0xff; send[15] = (x >> 0) & 0xff; /* * Send a command. */ if (!sendBytes(send, sizeof(send), 200 * TMOUT)) { printf("ouch02\n"); return SendError; } /* * Read the header of the response. */ uint8_t header[5]; if (!recvBytes(header, sizeof(header), 2 * 1000 * TMOUT)) { printf("ouch03\n"); return RecvError; } /* * Check the response and fetch an image data. */ if ((header[0] == 0x76) && (header[1] == 0x00) && (header[2] == 0x32) && (header[3] == 0x00) && (header[4] == 0x00)) { if (!recvBytes(body, sizeof(body), 2 * 1000 * TMOUT)) { printf("ouch04\n"); return RecvError; } siz_done += sizeof(body); if (func != NULL) { if (siz_done > siz_total) { siz_done = siz_total; } func(siz_done, siz_total, body, sizeof(body)); } for (int i = 1; i < sizeof(body); i++) { if ((body[i - 1] == 0xFF) && (body[i - 0] == 0xD9)) { end = true; } } } else { printf("ouch05\n"); return UnexpectedReply; } /* * Read the footer of the response. */ uint8_t footer[5]; if (!recvBytes(footer, sizeof(footer), 2 * 1000 * TMOUT)) { return RecvError; } m += sizeof(body); } while (!end); return NoError; } /** * Stop taking pictures. * * @return Error code. */ Camera_LS_Y201::ErrorCode Camera_LS_Y201::stopTakingPictures() { uint8_t send[5] = { 0x56, 0x00, 0x36, 0x01, 0x03 }; uint8_t recv[5]; if (!sendBytes(send, sizeof(send), 200 * TMOUT)) { return SendError; } if (!recvBytes(recv, sizeof(recv), 200 * TMOUT)) { return RecvError; } if ((recv[0] == 0x76) && (recv[1] == 0x00) && (recv[2] == 0x36) && (recv[3] == 0x00) && (recv[4] == 0x00)) { /* * I think the camera need a time for operating. * But there is no any comments on the documents. */ wait_ms(100); return NoError; } else { return UnexpectedReply; } } /** * Wait init end codes. * * @return True if the data sended. */ Camera_LS_Y201::ErrorCode Camera_LS_Y201::waitInitEnd() { static const char *PWR_ON_MSG = "Init end\x0d\x0a"; for (int i = 0; i < strlen(PWR_ON_MSG); i++) { static const int MAXCNT = 128; int cnt = 0; uint8_t c = 0x00; do { if (!recvBytes(&c, sizeof(c), 200 * TMOUT)) { return Timeout; } /* * What is the version of the camera. * You can check the version with this code. * * VC0703 1.00 * 3o ctrl in * Init end */ #if 0 printf("%c", c); #endif cnt++; if (MAXCNT < cnt) { return UnexpectedReply; } } while (c != PWR_ON_MSG[i]); } return NoError; } /** * 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 Camera_LS_Y201::sendBytes(uint8_t *buf, size_t len, int timeout_us) { for (uint32_t i = 0; i < (uint32_t)len; i++) { int cnt = 0; while (!serial.writeable()) { wait_us(1); cnt++; if (timeout_us < cnt) { return false; } } serial.putc(buf[i]); } 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 Camera_LS_Y201::recvBytes(uint8_t *buf, size_t len, int timeout_us) { for (uint32_t i = 0; i < (uint32_t)len; i++) { int cnt = 0; while (!serial.readable()) { wait_us(1); cnt++; if (timeout_us < cnt) { return false; } } buf[i] = serial.getc(); } return true; } /** * Wait received. * * @return True if the data received. */ bool Camera_LS_Y201::waitRecv() { while (!serial.readable()) { } return true; } /** * Wait idle state. */ bool Camera_LS_Y201::waitIdle() { while (serial.readable()) { serial.getc(); } return true; }