たけし みわ
/
y_CameraC1098_ES_01
Diff: CameraC1098/CameraC1098.cpp
- Revision:
- 0:5bf7e3564c3b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CameraC1098/CameraC1098.cpp Sun Jun 17 01:15:35 2012 +0000 @@ -0,0 +1,368 @@ +#include "mbed.h" +#include "CameraC1098.h" +//Camera() class +CameraC1098::CameraC1098(PinName tx, PinName rx, Baud baud) : serial(tx, rx) +{ + serial.baud((int)baud); +} +//inherited class +CameraC1098::~CameraC1098() {}; +//sync +bool CameraC1098::sync() +{ + waitIdle(); + + for (int i = 0; i < SYNCMAX; i++) { + if (true == sendSync()) { + if (true == recvAckOrNck()) { + if (true == recvSync()) { + if (true == sendAck(0x0D, 0x00)) { + wait_ms(500); + return true; + } + } + } + } + wait_ms(10); + } + return false; +} +//initial +bool CameraC1098::init(JpegResolution jr) +{ + waitIdle(); + bool en; + + en = sendInitial(jr); + if (true != en) {return en;} + waitRecv(); + en = recvAckOrNck(); + if (true != en) {return en;} + return true; +} +//new +bool CameraC1098::setupPackageSize(uint16_t packageSize) +{ + static bool alreadySetupPackageSize = false; + bool en; + if (!alreadySetupPackageSize) { + en = sendSetPackageSize(packageSize); + if (true != en) {return en;} + waitRecv(); + en = recvAckOrNck(); + if (true != en) {return en;} + alreadySetupPackageSize = true; + } + + return true; +} +//JpegSnapshotPicture +bool CameraC1098::getJpegSnapshotPicture(void(*func)(char *buf, size_t siz)) +{ + waitIdle(); + bool en; + + en = sendSnapshot(CompressedPicture, 1); + if (true != en) {return en;} + waitRecv(); + en = recvAckOrNck(); + if (true != en) {return en;} + + en = sendGetPicture(SnapshotPicture); + if (true != en) {return en;} + waitRecv(); + en = recvAckOrNck(); + if (true != en) {return en;} + //snapshot picture Data + DataType dt; + uint32_t length = 0; + waitRecv(); + en = recvData(&dt, &length); + if (true != en) {return en;} + en = sendAck(0x00, 0); + if (true != 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]; + waitRecv(); + if (!recvBytes(idbuf, sizeof(idbuf))) {return false;} + checksum += idbuf[0]; + checksum += idbuf[1]; + uint16_t id = (idbuf[1] << 8) | (idbuf[0] << 0); + if (id != i) {return false;} + // Size of the data. + char dsbuf[2]; + waitRecv(); + if (!recvBytes(dsbuf, sizeof(dsbuf))) {return false;} + // Received the data. + checksum += dsbuf[0]; + checksum += dsbuf[1]; + uint16_t ds = (dsbuf[1] << 8) | (dsbuf[0] << 0); + waitRecv(); + if (!recvBytes(&databuf[0], ds)) {return false;} + for (int j = 0; j < ds; j++) {checksum += databuf[j];} + // Verify code. + char vcbuf[2]; + waitRecv(); + if (!recvBytes(vcbuf, sizeof(vcbuf))) {return false;} + uint16_t vc = (vcbuf[1] << 8) | (vcbuf[0] << 0); + if (vc != (checksum & 0xff)) {return false;} + //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(50); + en = sendAck(0x00, 1 + i); + if (true != en) {return en;} + } + return true; +} + //NEW change baud rate 14400 -> 115200bps + bool CameraC1098::getnewbaud() + { + newbaud(); + return true; + } +//sendInitial +bool CameraC1098::sendInitial(JpegResolution jr) +{ + char send[COMMAND_LENGTH]; + send[0] = 0xAA; + send[1] = 0x01; + send[2] = 0x04;//115200bau + send[3] = 0x07;//JpegColor + send[4] = 0x00;//default + send[5] = (char)jr; + + if (!sendBytes(send, sizeof(send))) {return false; } + return true; +} +//sendgetPictyure +bool CameraC1098::sendGetPicture(PictureType pt) { + char send[COMMAND_LENGTH]; + send[0] = 0xAA; + send[1] = 0x04; + send[2] = 0x01;//(char)pt; + send[3] = 0x00; + send[4] = 0x00; + send[5] = 0x00; + + if (!sendBytes(send, sizeof(send))) {return false;} + return true; +} +//sendSnapshot +bool CameraC1098::sendSnapshot(SnapshotType st, uint16_t skipFrames) +{ + char send[COMMAND_LENGTH]; + send[0] = 0xAA; + send[1] = 0x05; + send[2] = 0x00;//(char)st; + send[3] = (skipFrames >> 0) & 0xff; + send[4] = (skipFrames >> 8) & 0xff; + send[5] = 0x00; + + if (!sendBytes(send, sizeof(send))) {return false;} + return true; +} +//sendSetOackagesize +bool CameraC1098::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 (!sendBytes(send, sizeof(send))) {return false;} + return true; +} +//sendSetBaudrate +//bool CameraC1098::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 (!sendBytes(send, sizeof(send))) {return false;} +// +// return true; +//} +//sendReset +bool CameraC1098::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] = 0x00;//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 (!sendBytes(send, sizeof(send))) {return false;} + return true; +} +//sendPowerOff +bool CameraC1098::sendPowerOff() +{ + char send[COMMAND_LENGTH]; + send[0] = 0xAA; + send[1] = 0x09; + send[2] = 0x00; + send[3] = 0x00; + send[4] = 0x00; + send[5] = 0x00; + + if (!sendBytes(send, sizeof(send))) {return false;} + return true; +} +//recvData +bool CameraC1098::recvData(DataType *dt, uint32_t *length) +{ + char recv[COMMAND_LENGTH]; + if (!recvBytes(recv, sizeof(recv))) {return false;} + if ((0xAA != recv[0]) || (0x0A != recv[1])) {return false;} + *dt = (DataType)recv[2]; + *length = (recv[5] << 16) | (recv[4] << 8) | (recv[3] << 0); + return true; +} +//sendSync +bool CameraC1098::sendSync() +{ + char send[COMMAND_LENGTH]; + send[0] = 0xAA; + send[1] = 0x0D; + send[2] = 0x00; + send[3] = 0x00; + send[4] = 0x00; + send[5] = 0x00; + if (!sendBytes(send, sizeof(send))) {return false;} + return true; +} +//recvSync +bool CameraC1098::recvSync() +{ + char recv[COMMAND_LENGTH]; + if (!recvBytes(recv, sizeof(recv))) {return false;} + if ((0xAA != recv[0]) || (0x0D != recv[1])) {return false;} + return true; +} +// SendAck +//@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. +bool CameraC1098::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 (!sendBytes(send, sizeof(send))) {return false;} + return true; +} +// Receive ACK or NCK. +bool CameraC1098::recvAckOrNck() +{ + char recv[COMMAND_LENGTH]; + if (!recvBytes(recv, sizeof(recv))) {return false;} + if ((0xAA == recv[0]) && (0x0E == recv[1])) {return true;} + if ((0xAA == recv[0]) && (0x0F == recv[1])) {return true;} + return false; +} +//Send bytes to camera module. +//@param buf Pointer to the data buffer. +//@param len Length of the data buffer. +bool CameraC1098::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. +bool CameraC1098::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. +bool CameraC1098::waitRecv() +{ + while (!serial.readable()) { + } + return true; +} +//Wait idle state. +bool CameraC1098::waitIdle() +{ + while (serial.readable()) { + serial.getc(); + } + return true; +} + //NEW change baud rate 14400 -> 115200bps + bool CameraC1098::newbaud() + { + Baud baud=CameraC1098::Baud115200; + serial.baud((int)baud); + return true; + }