Diff: CameraC1098/CameraC1098.cpp
- Revision:
- 0:5bf7e3564c3b
diff -r 000000000000 -r 5bf7e3564c3b CameraC1098/CameraC1098.cpp
--- /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;
+ }