this will take a image from C328 serial camera and store those images in mbed flash as html and this html page is uploaded into the server at ip:192.168.1.2
CameraC328.cpp
- Committer:
- mitesh2patel
- Date:
- 2010-12-15
- Revision:
- 0:e1a0471e5ffb
File content as of revision 0:e1a0471e5ffb:
/** * C328-7640 device driver class (Version 0.0.6) * Reference documents: C328-7640 User Manual v3.0 2004.8.19 * * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) * http://shinta.main.jp/ */ #include "CameraC328.h" #define WAITIDLE waitIdle #define SENDFUNC sendBytes #define RECVFUNC recvBytes #define WAITFUNC waitRecv /** * Constructor. * * @param tx A pin for transmit. * @param rx A pin for receive. * @param baud Baud rate. (Default is Baud19200.) */ CameraC328::CameraC328(PinName tx, PinName rx, Baud baud) : serial(tx, rx) { serial.baud((int)baud); } /** * Destructor. */ CameraC328::~CameraC328() { } /** * Make a sync. for baud rate. */ CameraC328::ErrorNumber CameraC328::sync() { WAITIDLE(); for (int i = 0; i < SYNCMAX; i++) { if (NoError == sendSync()) { if (NoError == recvAckOrNck()) { if (NoError == recvSync()) { if (NoError == sendAck(0x0D, 0x00)) { /* * After synchronization, the camera needs a little time for AEC and AGC to be stable. * Users should wait for 1-2 seconds before capturing the first picture. */ wait(2); return NoError; } } } } wait_ms(50); } return UnexpectedReply; } /** * Initialize. * * @param ct Color type. * @param rr Raw resolution. * @param jr JPEG resolution. */ CameraC328::ErrorNumber CameraC328::init(ColorType ct, RawResolution rr, JpegResolution jr) { WAITIDLE(); ErrorNumber en; en = sendInitial(ct, rr, jr); if (NoError != en) { return en; } WAITFUNC(); en = recvAckOrNck(); if (NoError != en) { return en; } static bool alreadySetupPackageSize = false; if (!alreadySetupPackageSize) { en = sendSetPackageSize(packageSize); if (NoError != en) { return en; } WAITFUNC(); en = recvAckOrNck(); if (NoError != en) { return en; } alreadySetupPackageSize = true; } return (ErrorNumber)NoError; } /** * Get uncompressed snapshot picture. * * @param func A pointer to a callback function. * Please do NOT block this callback function. * Because the camera module transmit image datas continuously. * @return Status of the error. */ CameraC328::ErrorNumber CameraC328::getUncompressedSnapshotPicture(void(*func)(size_t done, size_t total, char c)) { WAITIDLE(); ErrorNumber en; en = sendSnapshot(UncompressedPicture, 0); if (NoError != en) { return en; } WAITFUNC(); en = recvAckOrNck(); if (NoError != en) { return en; } en = sendGetPicture(SnapshotPicture); if (NoError != en) { return en; } WAITFUNC(); en = recvAckOrNck(); if (NoError != en) { return en; } /* * image data */ DataType dt; uint32_t length = 0; WAITFUNC(); en = recvData(&dt, &length); if (NoError != en) { return en; } size_t imgcnt = 0; for (int i = 0; i < (int)length; i++) { char c; WAITFUNC(); if (!RECVFUNC(&c, 1)) { return (ErrorNumber)UnexpectedReply; } imgcnt++; /* * Call a call back function. * Please do not block this function. */ func(imgcnt, length, c); } /* * ACK */ en = sendAck(0x0A, 0x00); if (NoError != en) { return en; } return (ErrorNumber)NoError; } /** * Get uncompressed preview picture. * * @param func A pointer to a callback function. * Please do NOT block this callback function. * Because the camera module transmit image datas continuously. * @return Status of the error. */ CameraC328::ErrorNumber CameraC328::getUncompressedPreviewPicture(void(*func)(size_t done, size_t total, char c)) { WAITIDLE(); ErrorNumber en; en = sendGetPicture(PreviewPicture); if (NoError != en) { return en; } WAITFUNC(); en = recvAckOrNck(); if (NoError != en) { return en; } /* * image data */ DataType dt; uint32_t length = 0; WAITFUNC(); en = recvData(&dt, &length); if (NoError != en) { return en; } size_t imgcnt = 0; for (int i = 0; i < (int)length; i++) { char c; WAITFUNC(); if (!RECVFUNC(&c, 1)) { return (ErrorNumber)UnexpectedReply; } imgcnt++; /* * Call a call back function. * Please do not block this function. */ func(imgcnt, length, c); } /* * ACK */ en = sendAck(0x0A, 0x00); if (NoError != en) { return en; } return (ErrorNumber)NoError; } /** * Get JPEG snapshot picture. * * @param func A pointer to a callback function. * You can block this function until saving the image datas. * @return Status of the error. */ CameraC328::ErrorNumber CameraC328::getJpegSnapshotPicture(void(*func)(char *buf, size_t siz)) { WAITIDLE(); ErrorNumber en; en = sendSnapshot(CompressedPicture, 1); if (NoError != en) { return en; } WAITFUNC(); en = recvAckOrNck(); if (NoError != en) { return en; } en = sendGetPicture(SnapshotPicture); if (NoError != en) { return en; } WAITFUNC(); en = recvAckOrNck(); if (NoError != en) { return en; } /* * Data : snapshot picture */ DataType dt; uint32_t length = 0; WAITFUNC(); en = recvData(&dt, &length); if (NoError != en) { return en; } en = sendAck(0x00, 0); if (NoError != en) { return en; } char databuf[packageSize - 6]; uint16_t pkg_total = length / (packageSize - 6); for (int i = 0; i <= (int)pkg_total; i++) { uint16_t checksum = 0; // ID. char idbuf[2]; WAITFUNC(); if (!RECVFUNC(idbuf, sizeof(idbuf))) { return (ErrorNumber)UnexpectedReply; } checksum += idbuf[0]; checksum += idbuf[1]; uint16_t id = (idbuf[1] << 8) | (idbuf[0] << 0); if (id != i) { return (ErrorNumber)UnexpectedReply; } // Size of the data. char dsbuf[2]; WAITFUNC(); if (!RECVFUNC(dsbuf, sizeof(dsbuf))) { return (ErrorNumber)UnexpectedReply; } // Received the data. checksum += dsbuf[0]; checksum += dsbuf[1]; uint16_t ds = (dsbuf[1] << 8) | (dsbuf[0] << 0); WAITFUNC(); if (!RECVFUNC(&databuf[0], ds)) { return (ErrorNumber)UnexpectedReply; } for (int j = 0; j < ds; j++) { checksum += databuf[j]; } // Verify code. char vcbuf[2]; WAITFUNC(); if (!RECVFUNC(vcbuf, sizeof(vcbuf))) { return (ErrorNumber)UnexpectedReply; } uint16_t vc = (vcbuf[1] << 8) | (vcbuf[0] << 0); if (vc != (checksum & 0xff)) { return (ErrorNumber)UnexpectedReply; } /* * Call a call back function. * You can block this function while working. */ func(databuf, ds); /* * We should wait for camera working before reply a ACK. */ wait_ms(100); en = sendAck(0x00, 1 + i); if (NoError != en) { return en; } } return (ErrorNumber)NoError; } /** * Get JPEG preview picture. * * @param func A pointer to a callback function. * You can block this function until saving the image datas. * @return Status of the error. */ CameraC328::ErrorNumber CameraC328::getJpegPreviewPicture(void(*func)(char *buf, size_t siz)) { WAITIDLE(); ErrorNumber en; en = sendGetPicture(JpegPreviewPicture); if (NoError != en) { return en; } WAITFUNC(); en = recvAckOrNck(); if (NoError != en) { return en; } /* * Data : JPEG preview picture */ DataType dt; uint32_t length = 0; WAITFUNC(); en = recvData(&dt, &length); if (NoError != en) { return en; } en = sendAck(0x00, 0); if (NoError != en) { return en; } char databuf[packageSize - 6]; uint16_t pkg_total = length / (packageSize - 6); for (int i = 0; i <= (int)pkg_total; i++) { uint16_t checksum = 0; // ID. char idbuf[2]; WAITFUNC(); if (!RECVFUNC(idbuf, sizeof(idbuf))) { return (ErrorNumber)UnexpectedReply; } checksum += idbuf[0]; checksum += idbuf[1]; uint16_t id = (idbuf[1] << 8) | (idbuf[0] << 0); if (id != i) { return (ErrorNumber)UnexpectedReply; } // Size of the data. char dsbuf[2]; WAITFUNC(); if (!RECVFUNC(dsbuf, sizeof(dsbuf))) { return (ErrorNumber)UnexpectedReply; } // Received the data. checksum += dsbuf[0]; checksum += dsbuf[1]; uint16_t ds = (dsbuf[1] << 8) | (dsbuf[0] << 0); WAITFUNC(); if (!RECVFUNC(&databuf[0], ds)) { return (ErrorNumber)UnexpectedReply; } for (int j = 0; j < ds; j++) { checksum += databuf[j]; } // Verify code. char vcbuf[2]; WAITFUNC(); if (!RECVFUNC(vcbuf, sizeof(vcbuf))) { return (ErrorNumber)UnexpectedReply; } uint16_t vc = (vcbuf[1] << 8) | (vcbuf[0] << 0); if (vc != (checksum & 0xff)) { return (ErrorNumber)UnexpectedReply; } /* * Call a call back function. * You can block this function while working. */ func(databuf, ds); /* * We should wait for camera working before reply a ACK. */ wait_ms(100); en = sendAck(0x00, 1 + i); if (NoError != en) { return en; } } return (ErrorNumber)NoError; } CameraC328::ErrorNumber CameraC328::sendInitial(ColorType ct, RawResolution rr, JpegResolution jr) { char send[COMMAND_LENGTH]; send[0] = 0xAA; send[1] = 0x01; send[2] = 0x00; send[3] = (char)ct; send[4] = (char)rr; send[5] = (char)jr; if (!SENDFUNC(send, sizeof(send))) { return (ErrorNumber)SendRegisterTimeout; } return (ErrorNumber)NoError; } CameraC328::ErrorNumber CameraC328::sendGetPicture(PictureType pt) { char send[COMMAND_LENGTH]; send[0] = 0xAA; send[1] = 0x04; send[2] = (char)pt; send[3] = 0x00; send[4] = 0x00; send[5] = 0x00; if (!SENDFUNC(send, sizeof(send))) { return (ErrorNumber)SendRegisterTimeout; } return (ErrorNumber)NoError; } CameraC328::ErrorNumber CameraC328::sendSnapshot(SnapshotType st, uint16_t skipFrames) { char send[COMMAND_LENGTH]; send[0] = 0xAA; send[1] = 0x05; send[2] = (char)st; send[3] = (skipFrames >> 0) & 0xff; send[4] = (skipFrames >> 8) & 0xff; send[5] = 0x00; if (!SENDFUNC(send, sizeof(send))) { return (ErrorNumber)SendRegisterTimeout; } return (ErrorNumber)NoError; } CameraC328::ErrorNumber CameraC328::sendSetPackageSize(uint16_t packageSize) { char send[COMMAND_LENGTH]; send[0] = 0xAA; send[1] = 0x06; send[2] = 0x08; send[3] = (packageSize >> 0) & 0xff; send[4] = (packageSize >> 8) & 0xff; send[5] = 0x00; if (!SENDFUNC(send, sizeof(send))) { return (ErrorNumber)SendRegisterTimeout; } return (ErrorNumber)NoError; } CameraC328::ErrorNumber CameraC328::sendSetBaudrate(Baud baud) { char send[COMMAND_LENGTH]; static struct baud_list { Baud baud; uint8_t div1st; uint8_t div2nd; } baudtable [] = { { Baud7200, 0xff, 0x01 }, { Baud9600, 0xbf, 0x01 }, { Baud14400, 0x7f, 0x01 }, { Baud19200, 0x5f, 0x01 }, { Baud28800, 0x3f, 0x01 }, { Baud38400, 0x2f, 0x01 }, { Baud57600, 0x1f, 0x01 }, { Baud115200, 0x0f, 0x01 } }; uint8_t div1st = 0x00, div2nd = 0x00; struct baud_list *p = &baudtable[0]; for (int i = 0; i < sizeof(baudtable) / sizeof(baudtable[0]); i++) { if (p->baud == baud) { div1st = p->div1st; div2nd = p->div2nd; } p++; } send[0] = 0xAA; send[1] = 0x07; send[2] = div1st; send[3] = div2nd; send[4] = 0x00; send[5] = 0x00; if (!SENDFUNC(send, sizeof(send))) { return (ErrorNumber)SendRegisterTimeout; } return (ErrorNumber)NoError; } CameraC328::ErrorNumber CameraC328::sendReset(ResetType rt, bool specialReset) { char send[COMMAND_LENGTH]; send[0] = 0xAA; send[1] = 0x08; send[2] = (int)rt; send[3] = 0x00; send[4] = 0x00; send[5] = specialReset ? 0xff : 0x00; /* * Special reset : If the parameter is 0xFF, the command is a special Reset command and the firmware responds to it immediately. */ if (!SENDFUNC(send, sizeof(send))) { return (ErrorNumber)SendRegisterTimeout; } return (ErrorNumber)NoError; } CameraC328::ErrorNumber CameraC328::sendPowerOff() { char send[COMMAND_LENGTH]; send[0] = 0xAA; send[1] = 0x09; send[2] = 0x00; send[3] = 0x00; send[4] = 0x00; send[5] = 0x00; if (!SENDFUNC(send, sizeof(send))) { return (ErrorNumber)SendRegisterTimeout; } return (ErrorNumber)NoError; } CameraC328::ErrorNumber CameraC328::recvData(DataType *dt, uint32_t *length) { char recv[COMMAND_LENGTH]; if (!RECVFUNC(recv, sizeof(recv))) { return (ErrorNumber)UnexpectedReply; } if ((0xAA != recv[0]) || (0x0A != recv[1])) { return (ErrorNumber)UnexpectedReply; } *dt = (DataType)recv[2]; *length = (recv[5] << 16) | (recv[4] << 8) | (recv[3] << 0); return (ErrorNumber)NoError; } CameraC328::ErrorNumber CameraC328::sendSync() { char send[COMMAND_LENGTH]; send[0] = 0xAA; send[1] = 0x0D; send[2] = 0x00; send[3] = 0x00; send[4] = 0x00; send[5] = 0x00; if (!SENDFUNC(send, sizeof(send))) { return (ErrorNumber)SendRegisterTimeout; } return (ErrorNumber)NoError; } CameraC328::ErrorNumber CameraC328::recvSync() { char recv[COMMAND_LENGTH]; if (!RECVFUNC(recv, sizeof(recv))) { return (ErrorNumber)UnexpectedReply; } if ((0xAA != recv[0]) || (0x0D != recv[1])) { return (ErrorNumber)UnexpectedReply; } return (ErrorNumber)NoError; } /** * Send ACK. * * @param commandId The command with that ID is acknowledged by this command. * @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. */ CameraC328::ErrorNumber CameraC328::sendAck(uint8_t commandId, uint16_t packageId) { char send[COMMAND_LENGTH]; send[0] = 0xAA; send[1] = 0x0E; send[2] = commandId; send[3] = 0x00; // ACK counter is not used. send[4] = (packageId >> 0) & 0xff; send[5] = (packageId >> 8) & 0xff; if (!SENDFUNC(send, sizeof(send))) { return (ErrorNumber)SendRegisterTimeout; } return (ErrorNumber)NoError; } /** * Receive ACK or NCK. * * @return Error number. */ CameraC328::ErrorNumber CameraC328::recvAckOrNck() { char recv[COMMAND_LENGTH]; if (!RECVFUNC(recv, sizeof(recv))) { return (ErrorNumber)UnexpectedReply; } if ((0xAA == recv[0]) && (0x0E == recv[1])) { return (ErrorNumber)NoError; } if ((0xAA == recv[0]) && (0x0F == recv[1])) { return (ErrorNumber)recv[4]; } return (ErrorNumber)UnexpectedReply; } /** * 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 CameraC328::sendBytes(char *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 CameraC328::recvBytes(char *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 CameraC328::waitRecv() { while (!serial.readable()) { } return true; } /** * Wait idle state. */ bool CameraC328::waitIdle() { while (serial.readable()) { serial.getc(); } return true; }