Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
CameraC1098/CameraC1098.cpp
- Committer:
- esmiwa
- Date:
- 2012-06-17
- Revision:
- 0:5bf7e3564c3b
File content as of revision 0:5bf7e3564c3b:
#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;
}