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.
CameraC328.cpp
00001 /** 00002 * C328-7640 device driver class (Version 0.0.6) 00003 * Reference documents: C328-7640 User Manual v3.0 2004.8.19 00004 * 00005 * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) 00006 * http://shinta.main.jp/ 00007 */ 00008 00009 #include "CameraC328.h" 00010 00011 #define WAITIDLE waitIdle 00012 #define SENDFUNC sendBytes 00013 #define RECVFUNC recvBytes 00014 #define WAITFUNC waitRecv 00015 00016 /** 00017 * Constructor. 00018 * 00019 * @param tx A pin for transmit. 00020 * @param rx A pin for receive. 00021 * @param baud Baud rate. (Default is Baud19200.) 00022 */ 00023 CameraC328::CameraC328(PinName tx, PinName rx, Baud baud) : serial(tx, rx) { 00024 serial.baud((int)baud); 00025 } 00026 00027 /** 00028 * Destructor. 00029 */ 00030 CameraC328::~CameraC328() { 00031 } 00032 00033 /** 00034 * Make a sync. for baud rate. 00035 */ 00036 CameraC328::ErrorNumber CameraC328::sync() { 00037 WAITIDLE(); 00038 00039 for (int i = 0; i < SYNCMAX; i++) { 00040 if (NoError == sendSync()) { 00041 if (NoError == recvAckOrNck()) { 00042 if (NoError == recvSync()) { 00043 if (NoError == sendAck(0x0D, 0x00)) { 00044 /* 00045 * After synchronization, the camera needs a little time for AEC and AGC to be stable. 00046 * Users should wait for 1-2 seconds before capturing the first picture. 00047 */ 00048 wait(2); 00049 return NoError; 00050 } 00051 } 00052 } 00053 } 00054 wait_ms(50); 00055 } 00056 return UnexpectedReply; 00057 } 00058 00059 /** 00060 * Initialize. 00061 * 00062 * @param ct Color type. 00063 * @param rr Raw resolution. 00064 * @param jr JPEG resolution. 00065 */ 00066 CameraC328::ErrorNumber CameraC328::init(ColorType ct, RawResolution rr, JpegResolution jr) { 00067 WAITIDLE(); 00068 ErrorNumber en; 00069 00070 en = sendInitial(ct, rr, jr); 00071 if (NoError != en) { 00072 return en; 00073 } 00074 WAITFUNC(); 00075 en = recvAckOrNck(); 00076 if (NoError != en) { 00077 return en; 00078 } 00079 00080 static bool alreadySetupPackageSize = false; 00081 if (!alreadySetupPackageSize) { 00082 en = sendSetPackageSize(packageSize); 00083 if (NoError != en) { 00084 return en; 00085 } 00086 WAITFUNC(); 00087 en = recvAckOrNck(); 00088 if (NoError != en) { 00089 return en; 00090 } 00091 alreadySetupPackageSize = true; 00092 } 00093 00094 return (ErrorNumber)NoError; 00095 } 00096 00097 /** 00098 * Get uncompressed snapshot picture. 00099 * 00100 * @param func A pointer to a callback function. 00101 * Please do NOT block this callback function. 00102 * Because the camera module transmit image datas continuously. 00103 * @return Status of the error. 00104 */ 00105 CameraC328::ErrorNumber CameraC328::getUncompressedSnapshotPicture(void(*func)(size_t done, size_t total, char c)) { 00106 WAITIDLE(); 00107 ErrorNumber en; 00108 00109 en = sendSnapshot(UncompressedPicture, 0); 00110 if (NoError != en) { 00111 return en; 00112 } 00113 WAITFUNC(); 00114 en = recvAckOrNck(); 00115 if (NoError != en) { 00116 return en; 00117 } 00118 00119 en = sendGetPicture(SnapshotPicture); 00120 if (NoError != en) { 00121 return en; 00122 } 00123 WAITFUNC(); 00124 en = recvAckOrNck(); 00125 if (NoError != en) { 00126 return en; 00127 } 00128 00129 /* 00130 * image data 00131 */ 00132 DataType dt; 00133 uint32_t length = 0; 00134 WAITFUNC(); 00135 en = recvData(&dt, &length); 00136 if (NoError != en) { 00137 return en; 00138 } 00139 size_t imgcnt = 0; 00140 for (int i = 0; i < (int)length; i++) { 00141 char c; 00142 WAITFUNC(); 00143 if (!RECVFUNC(&c, 1)) { 00144 return (ErrorNumber)UnexpectedReply; 00145 } 00146 imgcnt++; 00147 00148 /* 00149 * Call a call back function. 00150 * Please do not block this function. 00151 */ 00152 func(imgcnt, length, c); 00153 } 00154 00155 /* 00156 * ACK 00157 */ 00158 en = sendAck(0x0A, 0x00); 00159 if (NoError != en) { 00160 return en; 00161 } 00162 00163 return (ErrorNumber)NoError; 00164 } 00165 00166 /** 00167 * Get uncompressed preview picture. 00168 * 00169 * @param func A pointer to a callback function. 00170 * Please do NOT block this callback function. 00171 * Because the camera module transmit image datas continuously. 00172 * @return Status of the error. 00173 */ 00174 CameraC328::ErrorNumber CameraC328::getUncompressedPreviewPicture(void(*func)(size_t done, size_t total, char c)) { 00175 WAITIDLE(); 00176 ErrorNumber en; 00177 00178 en = sendGetPicture(PreviewPicture); 00179 if (NoError != en) { 00180 return en; 00181 } 00182 WAITFUNC(); 00183 en = recvAckOrNck(); 00184 if (NoError != en) { 00185 return en; 00186 } 00187 00188 /* 00189 * image data 00190 */ 00191 DataType dt; 00192 uint32_t length = 0; 00193 WAITFUNC(); 00194 en = recvData(&dt, &length); 00195 if (NoError != en) { 00196 return en; 00197 } 00198 size_t imgcnt = 0; 00199 for (int i = 0; i < (int)length; i++) { 00200 char c; 00201 WAITFUNC(); 00202 if (!RECVFUNC(&c, 1)) { 00203 return (ErrorNumber)UnexpectedReply; 00204 } 00205 imgcnt++; 00206 00207 /* 00208 * Call a call back function. 00209 * Please do not block this function. 00210 */ 00211 func(imgcnt, length, c); 00212 } 00213 00214 /* 00215 * ACK 00216 */ 00217 en = sendAck(0x0A, 0x00); 00218 if (NoError != en) { 00219 return en; 00220 } 00221 00222 return (ErrorNumber)NoError; 00223 } 00224 00225 /** 00226 * Get JPEG snapshot picture. 00227 * 00228 * @param func A pointer to a callback function. 00229 * You can block this function until saving the image datas. 00230 * @return Status of the error. 00231 */ 00232 CameraC328::ErrorNumber CameraC328::getJpegSnapshotPicture(void(*func)(char *buf, size_t siz)) { 00233 WAITIDLE(); 00234 ErrorNumber en; 00235 00236 en = sendSnapshot(CompressedPicture, 1); 00237 if (NoError != en) { 00238 return en; 00239 } 00240 WAITFUNC(); 00241 en = recvAckOrNck(); 00242 if (NoError != en) { 00243 return en; 00244 } 00245 00246 en = sendGetPicture(SnapshotPicture); 00247 if (NoError != en) { 00248 return en; 00249 } 00250 WAITFUNC(); 00251 en = recvAckOrNck(); 00252 if (NoError != en) { 00253 return en; 00254 } 00255 00256 /* 00257 * Data : snapshot picture 00258 */ 00259 DataType dt; 00260 uint32_t length = 0; 00261 WAITFUNC(); 00262 en = recvData(&dt, &length); 00263 if (NoError != en) { 00264 return en; 00265 } 00266 en = sendAck(0x00, 0); 00267 if (NoError != en) { 00268 return en; 00269 } 00270 00271 char databuf[packageSize - 6]; 00272 uint16_t pkg_total = length / (packageSize - 6); 00273 for (int i = 0; i <= (int)pkg_total; i++) { 00274 uint16_t checksum = 0; 00275 // ID. 00276 char idbuf[2]; 00277 WAITFUNC(); 00278 if (!RECVFUNC(idbuf, sizeof(idbuf))) { 00279 return (ErrorNumber)UnexpectedReply; 00280 } 00281 checksum += idbuf[0]; 00282 checksum += idbuf[1]; 00283 uint16_t id = (idbuf[1] << 8) | (idbuf[0] << 0); 00284 if (id != i) { 00285 return (ErrorNumber)UnexpectedReply; 00286 } 00287 00288 // Size of the data. 00289 char dsbuf[2]; 00290 WAITFUNC(); 00291 if (!RECVFUNC(dsbuf, sizeof(dsbuf))) { 00292 return (ErrorNumber)UnexpectedReply; 00293 } 00294 00295 // Received the data. 00296 checksum += dsbuf[0]; 00297 checksum += dsbuf[1]; 00298 uint16_t ds = (dsbuf[1] << 8) | (dsbuf[0] << 0); 00299 WAITFUNC(); 00300 if (!RECVFUNC(&databuf[0], ds)) { 00301 return (ErrorNumber)UnexpectedReply; 00302 } 00303 for (int j = 0; j < ds; j++) { 00304 checksum += databuf[j]; 00305 } 00306 00307 // Verify code. 00308 char vcbuf[2]; 00309 WAITFUNC(); 00310 if (!RECVFUNC(vcbuf, sizeof(vcbuf))) { 00311 return (ErrorNumber)UnexpectedReply; 00312 } 00313 uint16_t vc = (vcbuf[1] << 8) | (vcbuf[0] << 0); 00314 if (vc != (checksum & 0xff)) { 00315 return (ErrorNumber)UnexpectedReply; 00316 } 00317 00318 /* 00319 * Call a call back function. 00320 * You can block this function while working. 00321 */ 00322 func(databuf, ds); 00323 00324 /* 00325 * We should wait for camera working before reply a ACK. 00326 */ 00327 wait_ms(100); 00328 en = sendAck(0x00, 1 + i); 00329 if (NoError != en) { 00330 return en; 00331 } 00332 } 00333 00334 return (ErrorNumber)NoError; 00335 } 00336 00337 /** 00338 * Get JPEG preview picture. 00339 * 00340 * @param func A pointer to a callback function. 00341 * You can block this function until saving the image datas. 00342 * @return Status of the error. 00343 */ 00344 CameraC328::ErrorNumber CameraC328::getJpegPreviewPicture(void(*func)(char *buf, size_t siz)) { 00345 WAITIDLE(); 00346 ErrorNumber en; 00347 00348 en = sendGetPicture(JpegPreviewPicture); 00349 if (NoError != en) { 00350 return en; 00351 } 00352 WAITFUNC(); 00353 en = recvAckOrNck(); 00354 if (NoError != en) { 00355 return en; 00356 } 00357 00358 /* 00359 * Data : JPEG preview picture 00360 */ 00361 DataType dt; 00362 uint32_t length = 0; 00363 WAITFUNC(); 00364 en = recvData(&dt, &length); 00365 if (NoError != en) { 00366 return en; 00367 } 00368 en = sendAck(0x00, 0); 00369 if (NoError != en) { 00370 return en; 00371 } 00372 00373 char databuf[packageSize - 6]; 00374 uint16_t pkg_total = length / (packageSize - 6); 00375 for (int i = 0; i <= (int)pkg_total; i++) { 00376 uint16_t checksum = 0; 00377 // ID. 00378 char idbuf[2]; 00379 WAITFUNC(); 00380 if (!RECVFUNC(idbuf, sizeof(idbuf))) { 00381 return (ErrorNumber)UnexpectedReply; 00382 } 00383 checksum += idbuf[0]; 00384 checksum += idbuf[1]; 00385 uint16_t id = (idbuf[1] << 8) | (idbuf[0] << 0); 00386 if (id != i) { 00387 return (ErrorNumber)UnexpectedReply; 00388 } 00389 00390 // Size of the data. 00391 char dsbuf[2]; 00392 WAITFUNC(); 00393 if (!RECVFUNC(dsbuf, sizeof(dsbuf))) { 00394 return (ErrorNumber)UnexpectedReply; 00395 } 00396 00397 // Received the data. 00398 checksum += dsbuf[0]; 00399 checksum += dsbuf[1]; 00400 uint16_t ds = (dsbuf[1] << 8) | (dsbuf[0] << 0); 00401 WAITFUNC(); 00402 if (!RECVFUNC(&databuf[0], ds)) { 00403 return (ErrorNumber)UnexpectedReply; 00404 } 00405 for (int j = 0; j < ds; j++) { 00406 checksum += databuf[j]; 00407 } 00408 00409 // Verify code. 00410 char vcbuf[2]; 00411 WAITFUNC(); 00412 if (!RECVFUNC(vcbuf, sizeof(vcbuf))) { 00413 return (ErrorNumber)UnexpectedReply; 00414 } 00415 uint16_t vc = (vcbuf[1] << 8) | (vcbuf[0] << 0); 00416 if (vc != (checksum & 0xff)) { 00417 return (ErrorNumber)UnexpectedReply; 00418 } 00419 00420 /* 00421 * Call a call back function. 00422 * You can block this function while working. 00423 */ 00424 func(databuf, ds); 00425 00426 /* 00427 * We should wait for camera working before reply a ACK. 00428 */ 00429 wait_ms(100); 00430 en = sendAck(0x00, 1 + i); 00431 if (NoError != en) { 00432 return en; 00433 } 00434 } 00435 00436 return (ErrorNumber)NoError; 00437 } 00438 00439 CameraC328::ErrorNumber CameraC328::sendInitial(ColorType ct, RawResolution rr, JpegResolution jr) { 00440 char send[COMMAND_LENGTH]; 00441 00442 send[0] = 0xAA; 00443 send[1] = 0x01; 00444 send[2] = 0x00; 00445 send[3] = (char)ct; 00446 send[4] = (char)rr; 00447 send[5] = (char)jr; 00448 00449 if (!SENDFUNC(send, sizeof(send))) { 00450 return (ErrorNumber)SendRegisterTimeout; 00451 } 00452 return (ErrorNumber)NoError; 00453 } 00454 00455 CameraC328::ErrorNumber CameraC328::sendGetPicture(PictureType pt) { 00456 char send[COMMAND_LENGTH]; 00457 00458 send[0] = 0xAA; 00459 send[1] = 0x04; 00460 send[2] = (char)pt; 00461 send[3] = 0x00; 00462 send[4] = 0x00; 00463 send[5] = 0x00; 00464 00465 if (!SENDFUNC(send, sizeof(send))) { 00466 return (ErrorNumber)SendRegisterTimeout; 00467 } 00468 return (ErrorNumber)NoError; 00469 } 00470 00471 CameraC328::ErrorNumber CameraC328::sendSnapshot(SnapshotType st, uint16_t skipFrames) { 00472 char send[COMMAND_LENGTH]; 00473 send[0] = 0xAA; 00474 send[1] = 0x05; 00475 send[2] = (char)st; 00476 send[3] = (skipFrames >> 0) & 0xff; 00477 send[4] = (skipFrames >> 8) & 0xff; 00478 send[5] = 0x00; 00479 00480 if (!SENDFUNC(send, sizeof(send))) { 00481 return (ErrorNumber)SendRegisterTimeout; 00482 } 00483 return (ErrorNumber)NoError; 00484 } 00485 00486 CameraC328::ErrorNumber CameraC328::sendSetPackageSize(uint16_t packageSize) { 00487 char send[COMMAND_LENGTH]; 00488 send[0] = 0xAA; 00489 send[1] = 0x06; 00490 send[2] = 0x08; 00491 send[3] = (packageSize >> 0) & 0xff; 00492 send[4] = (packageSize >> 8) & 0xff; 00493 send[5] = 0x00; 00494 00495 if (!SENDFUNC(send, sizeof(send))) { 00496 return (ErrorNumber)SendRegisterTimeout; 00497 } 00498 return (ErrorNumber)NoError; 00499 } 00500 00501 CameraC328::ErrorNumber CameraC328::sendSetBaudrate(Baud baud) { 00502 char send[COMMAND_LENGTH]; 00503 00504 static struct baud_list { 00505 Baud baud; 00506 uint8_t div1st; 00507 uint8_t div2nd; 00508 } baudtable [] = { 00509 { Baud7200, 0xff, 0x01 }, 00510 { Baud9600, 0xbf, 0x01 }, 00511 { Baud14400, 0x7f, 0x01 }, 00512 { Baud19200, 0x5f, 0x01 }, 00513 { Baud28800, 0x3f, 0x01 }, 00514 { Baud38400, 0x2f, 0x01 }, 00515 { Baud57600, 0x1f, 0x01 }, 00516 { Baud115200, 0x0f, 0x01 } 00517 }; 00518 00519 uint8_t div1st = 0x00, div2nd = 0x00; 00520 struct baud_list *p = &baudtable[0]; 00521 for (int i = 0; i < sizeof(baudtable) / sizeof(baudtable[0]); i++) { 00522 if (p->baud == baud) { 00523 div1st = p->div1st; 00524 div2nd = p->div2nd; 00525 } 00526 p++; 00527 } 00528 00529 send[0] = 0xAA; 00530 send[1] = 0x07; 00531 send[2] = div1st; 00532 send[3] = div2nd; 00533 send[4] = 0x00; 00534 send[5] = 0x00; 00535 00536 if (!SENDFUNC(send, sizeof(send))) { 00537 return (ErrorNumber)SendRegisterTimeout; 00538 } 00539 00540 return (ErrorNumber)NoError; 00541 } 00542 00543 CameraC328::ErrorNumber CameraC328::sendReset(ResetType rt, bool specialReset) { 00544 char send[COMMAND_LENGTH]; 00545 send[0] = 0xAA; 00546 send[1] = 0x08; 00547 send[2] = (int)rt; 00548 send[3] = 0x00; 00549 send[4] = 0x00; 00550 send[5] = specialReset ? 0xff : 0x00; 00551 /* 00552 * Special reset : If the parameter is 0xFF, the command is a special Reset command and the firmware responds to it immediately. 00553 */ 00554 00555 if (!SENDFUNC(send, sizeof(send))) { 00556 return (ErrorNumber)SendRegisterTimeout; 00557 } 00558 00559 return (ErrorNumber)NoError; 00560 } 00561 00562 CameraC328::ErrorNumber CameraC328::sendPowerOff() { 00563 char send[COMMAND_LENGTH]; 00564 send[0] = 0xAA; 00565 send[1] = 0x09; 00566 send[2] = 0x00; 00567 send[3] = 0x00; 00568 send[4] = 0x00; 00569 send[5] = 0x00; 00570 00571 if (!SENDFUNC(send, sizeof(send))) { 00572 return (ErrorNumber)SendRegisterTimeout; 00573 } 00574 00575 return (ErrorNumber)NoError; 00576 } 00577 00578 CameraC328::ErrorNumber CameraC328::recvData(DataType *dt, uint32_t *length) { 00579 char recv[COMMAND_LENGTH]; 00580 if (!RECVFUNC(recv, sizeof(recv))) { 00581 return (ErrorNumber)UnexpectedReply; 00582 } 00583 if ((0xAA != recv[0]) || (0x0A != recv[1])) { 00584 return (ErrorNumber)UnexpectedReply; 00585 } 00586 *dt = (DataType)recv[2]; 00587 *length = (recv[5] << 16) | (recv[4] << 8) | (recv[3] << 0); 00588 return (ErrorNumber)NoError; 00589 } 00590 00591 CameraC328::ErrorNumber CameraC328::sendSync() { 00592 char send[COMMAND_LENGTH]; 00593 send[0] = 0xAA; 00594 send[1] = 0x0D; 00595 send[2] = 0x00; 00596 send[3] = 0x00; 00597 send[4] = 0x00; 00598 send[5] = 0x00; 00599 if (!SENDFUNC(send, sizeof(send))) { 00600 return (ErrorNumber)SendRegisterTimeout; 00601 } 00602 return (ErrorNumber)NoError; 00603 } 00604 00605 CameraC328::ErrorNumber CameraC328::recvSync() { 00606 char recv[COMMAND_LENGTH]; 00607 if (!RECVFUNC(recv, sizeof(recv))) { 00608 return (ErrorNumber)UnexpectedReply; 00609 } 00610 if ((0xAA != recv[0]) || (0x0D != recv[1])) { 00611 return (ErrorNumber)UnexpectedReply; 00612 } 00613 return (ErrorNumber)NoError; 00614 } 00615 00616 /** 00617 * Send ACK. 00618 * 00619 * @param commandId The command with that ID is acknowledged by this command. 00620 * @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. 00621 */ 00622 CameraC328::ErrorNumber CameraC328::sendAck(uint8_t commandId, uint16_t packageId) { 00623 char send[COMMAND_LENGTH]; 00624 send[0] = 0xAA; 00625 send[1] = 0x0E; 00626 send[2] = commandId; 00627 send[3] = 0x00; // ACK counter is not used. 00628 send[4] = (packageId >> 0) & 0xff; 00629 send[5] = (packageId >> 8) & 0xff; 00630 if (!SENDFUNC(send, sizeof(send))) { 00631 return (ErrorNumber)SendRegisterTimeout; 00632 } 00633 return (ErrorNumber)NoError; 00634 } 00635 00636 /** 00637 * Receive ACK or NCK. 00638 * 00639 * @return Error number. 00640 */ 00641 CameraC328::ErrorNumber CameraC328::recvAckOrNck() { 00642 char recv[COMMAND_LENGTH]; 00643 if (!RECVFUNC(recv, sizeof(recv))) { 00644 return (ErrorNumber)UnexpectedReply; 00645 } 00646 if ((0xAA == recv[0]) && (0x0E == recv[1])) { 00647 return (ErrorNumber)NoError; 00648 } 00649 if ((0xAA == recv[0]) && (0x0F == recv[1])) { 00650 return (ErrorNumber)recv[4]; 00651 } 00652 return (ErrorNumber)UnexpectedReply; 00653 } 00654 00655 /** 00656 * Send bytes to camera module. 00657 * 00658 * @param buf Pointer to the data buffer. 00659 * @param len Length of the data buffer. 00660 * 00661 * @return True if the data sended. 00662 */ 00663 bool CameraC328::sendBytes(char *buf, size_t len, int timeout_us) { 00664 for (uint32_t i = 0; i < (uint32_t)len; i++) { 00665 int cnt = 0; 00666 while (!serial.writeable()) { 00667 wait_us(1); 00668 cnt++; 00669 if (timeout_us < cnt) { 00670 return false; 00671 } 00672 } 00673 serial.putc(buf[i]); 00674 } 00675 return true; 00676 } 00677 00678 /** 00679 * Receive bytes from camera module. 00680 * 00681 * @param buf Pointer to the data buffer. 00682 * @param len Length of the data buffer. 00683 * 00684 * @return True if the data received. 00685 */ 00686 bool CameraC328::recvBytes(char *buf, size_t len, int timeout_us) { 00687 for (uint32_t i = 0; i < (uint32_t)len; i++) { 00688 int cnt = 0; 00689 while (!serial.readable()) { 00690 wait_us(1); 00691 cnt++; 00692 if (timeout_us < cnt) { 00693 return false; 00694 } 00695 } 00696 buf[i] = serial.getc(); 00697 } 00698 return true; 00699 } 00700 00701 /** 00702 * Wait received. 00703 * 00704 * @return True if the data received. 00705 */ 00706 bool CameraC328::waitRecv() { 00707 while (!serial.readable()) { 00708 } 00709 return true; 00710 } 00711 00712 /** 00713 * Wait idle state. 00714 */ 00715 bool CameraC328::waitIdle() { 00716 while (serial.readable()) { 00717 serial.getc(); 00718 } 00719 return true; 00720 }
Generated on Tue Jul 12 2022 20:39:37 by
1.7.2