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.
Dependents: Camera_C328_HTTP_SDcard_file_server_WIZwiki-W7500
Fork of CameraC328 by
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 00274 for (int i = 0; i <= (int)pkg_total; i++) { 00275 00276 printf(".\r\n"); // check it on the processing 00277 00278 uint16_t checksum = 0; 00279 // ID. 00280 char idbuf[2]; 00281 WAITFUNC(); 00282 if (!RECVFUNC(idbuf, sizeof(idbuf))) { 00283 return (ErrorNumber)UnexpectedReply; 00284 } 00285 checksum += idbuf[0]; 00286 checksum += idbuf[1]; 00287 uint16_t id = (idbuf[1] << 8) | (idbuf[0] << 0); 00288 if (id != i) { 00289 return (ErrorNumber)UnexpectedReply; 00290 } 00291 00292 // Size of the data. 00293 char dsbuf[2]; 00294 WAITFUNC(); 00295 if (!RECVFUNC(dsbuf, sizeof(dsbuf))) { 00296 return (ErrorNumber)UnexpectedReply; 00297 } 00298 00299 // Received the data. 00300 checksum += dsbuf[0]; 00301 checksum += dsbuf[1]; 00302 uint16_t ds = (dsbuf[1] << 8) | (dsbuf[0] << 0); 00303 WAITFUNC(); 00304 if (!RECVFUNC(&databuf[0], ds)) { 00305 return (ErrorNumber)UnexpectedReply; 00306 } 00307 for (int j = 0; j < ds; j++) { 00308 checksum += databuf[j]; 00309 } 00310 00311 // Verify code. 00312 char vcbuf[2]; 00313 WAITFUNC(); 00314 if (!RECVFUNC(vcbuf, sizeof(vcbuf))) { 00315 return (ErrorNumber)UnexpectedReply; 00316 } 00317 uint16_t vc = (vcbuf[1] << 8) | (vcbuf[0] << 0); 00318 if (vc != (checksum & 0xff)) { 00319 return (ErrorNumber)UnexpectedReply; 00320 } 00321 00322 /* 00323 * Call a call back function. 00324 * You can block this function while working. 00325 */ 00326 func(databuf, ds); 00327 00328 /* 00329 * We should wait for camera working before reply a ACK. 00330 */ 00331 wait_ms(100); 00332 en = sendAck(0x00, 1 + i); 00333 if (NoError != en) { 00334 return en; 00335 } 00336 } 00337 return (ErrorNumber)NoError; 00338 } 00339 00340 /** 00341 * Get JPEG preview picture. 00342 * 00343 * @param func A pointer to a callback function. 00344 * You can block this function until saving the image datas. 00345 * @return Status of the error. 00346 */ 00347 CameraC328::ErrorNumber CameraC328::getJpegPreviewPicture(void(*func)(char *buf, size_t siz)) { 00348 WAITIDLE(); 00349 ErrorNumber en; 00350 00351 en = sendGetPicture(JpegPreviewPicture); 00352 if (NoError != en) { 00353 return en; 00354 } 00355 WAITFUNC(); 00356 en = recvAckOrNck(); 00357 if (NoError != en) { 00358 return en; 00359 } 00360 00361 /* 00362 * Data : JPEG preview picture 00363 */ 00364 DataType dt; 00365 uint32_t length = 0; 00366 WAITFUNC(); 00367 en = recvData(&dt, &length); 00368 if (NoError != en) { 00369 return en; 00370 } 00371 en = sendAck(0x00, 0); 00372 if (NoError != en) { 00373 return en; 00374 } 00375 00376 char databuf[packageSize - 6]; 00377 uint16_t pkg_total = length / (packageSize - 6); 00378 for (int i = 0; i <= (int)pkg_total; i++) { 00379 uint16_t checksum = 0; 00380 // ID. 00381 char idbuf[2]; 00382 WAITFUNC(); 00383 if (!RECVFUNC(idbuf, sizeof(idbuf))) { 00384 return (ErrorNumber)UnexpectedReply; 00385 } 00386 checksum += idbuf[0]; 00387 checksum += idbuf[1]; 00388 uint16_t id = (idbuf[1] << 8) | (idbuf[0] << 0); 00389 if (id != i) { 00390 return (ErrorNumber)UnexpectedReply; 00391 } 00392 00393 // Size of the data. 00394 char dsbuf[2]; 00395 WAITFUNC(); 00396 if (!RECVFUNC(dsbuf, sizeof(dsbuf))) { 00397 return (ErrorNumber)UnexpectedReply; 00398 } 00399 00400 // Received the data. 00401 checksum += dsbuf[0]; 00402 checksum += dsbuf[1]; 00403 uint16_t ds = (dsbuf[1] << 8) | (dsbuf[0] << 0); 00404 WAITFUNC(); 00405 if (!RECVFUNC(&databuf[0], ds)) { 00406 return (ErrorNumber)UnexpectedReply; 00407 } 00408 for (int j = 0; j < ds; j++) { 00409 checksum += databuf[j]; 00410 } 00411 00412 // Verify code. 00413 char vcbuf[2]; 00414 WAITFUNC(); 00415 if (!RECVFUNC(vcbuf, sizeof(vcbuf))) { 00416 return (ErrorNumber)UnexpectedReply; 00417 } 00418 uint16_t vc = (vcbuf[1] << 8) | (vcbuf[0] << 0); 00419 if (vc != (checksum & 0xff)) { 00420 return (ErrorNumber)UnexpectedReply; 00421 } 00422 00423 /* 00424 * Call a call back function. 00425 * You can block this function while working. 00426 */ 00427 func(databuf, ds); 00428 00429 /* 00430 * We should wait for camera working before reply a ACK. 00431 */ 00432 wait_ms(100); 00433 en = sendAck(0x00, 1 + i); 00434 if (NoError != en) { 00435 return en; 00436 } 00437 } 00438 00439 return (ErrorNumber)NoError; 00440 } 00441 00442 CameraC328::ErrorNumber CameraC328::sendInitial(ColorType ct, RawResolution rr, JpegResolution jr) { 00443 char send[COMMAND_LENGTH]; 00444 00445 send[0] = 0xAA; 00446 send[1] = 0x01; 00447 send[2] = 0x00; 00448 send[3] = (char)ct; 00449 send[4] = (char)rr; 00450 send[5] = (char)jr; 00451 00452 if (!SENDFUNC(send, sizeof(send))) { 00453 return (ErrorNumber)SendRegisterTimeout; 00454 } 00455 return (ErrorNumber)NoError; 00456 } 00457 00458 CameraC328::ErrorNumber CameraC328::sendGetPicture(PictureType pt) { 00459 char send[COMMAND_LENGTH]; 00460 00461 send[0] = 0xAA; 00462 send[1] = 0x04; 00463 send[2] = (char)pt; 00464 send[3] = 0x00; 00465 send[4] = 0x00; 00466 send[5] = 0x00; 00467 00468 if (!SENDFUNC(send, sizeof(send))) { 00469 return (ErrorNumber)SendRegisterTimeout; 00470 } 00471 return (ErrorNumber)NoError; 00472 } 00473 00474 CameraC328::ErrorNumber CameraC328::sendSnapshot(SnapshotType st, uint16_t skipFrames) { 00475 char send[COMMAND_LENGTH]; 00476 send[0] = 0xAA; 00477 send[1] = 0x05; 00478 send[2] = (char)st; 00479 send[3] = (skipFrames >> 0) & 0xff; 00480 send[4] = (skipFrames >> 8) & 0xff; 00481 send[5] = 0x00; 00482 00483 if (!SENDFUNC(send, sizeof(send))) { 00484 return (ErrorNumber)SendRegisterTimeout; 00485 } 00486 return (ErrorNumber)NoError; 00487 } 00488 00489 CameraC328::ErrorNumber CameraC328::sendSetPackageSize(uint16_t packageSize) { 00490 char send[COMMAND_LENGTH]; 00491 send[0] = 0xAA; 00492 send[1] = 0x06; 00493 send[2] = 0x08; 00494 send[3] = (packageSize >> 0) & 0xff; 00495 send[4] = (packageSize >> 8) & 0xff; 00496 send[5] = 0x00; 00497 00498 if (!SENDFUNC(send, sizeof(send))) { 00499 return (ErrorNumber)SendRegisterTimeout; 00500 } 00501 return (ErrorNumber)NoError; 00502 } 00503 00504 CameraC328::ErrorNumber CameraC328::sendSetBaudrate(Baud baud) { 00505 char send[COMMAND_LENGTH]; 00506 00507 static struct baud_list { 00508 Baud baud; 00509 uint8_t div1st; 00510 uint8_t div2nd; 00511 } baudtable [] = { 00512 { Baud7200, 0xff, 0x01 }, 00513 { Baud9600, 0xbf, 0x01 }, 00514 { Baud14400, 0x7f, 0x01 }, 00515 { Baud19200, 0x5f, 0x01 }, 00516 { Baud28800, 0x3f, 0x01 }, 00517 { Baud38400, 0x2f, 0x01 }, 00518 { Baud57600, 0x1f, 0x01 }, 00519 { Baud115200, 0x0f, 0x01 } 00520 }; 00521 00522 uint8_t div1st = 0x00, div2nd = 0x00; 00523 struct baud_list *p = &baudtable[0]; 00524 for (int i = 0; i < sizeof(baudtable) / sizeof(baudtable[0]); i++) { 00525 if (p->baud == baud) { 00526 div1st = p->div1st; 00527 div2nd = p->div2nd; 00528 } 00529 p++; 00530 } 00531 00532 send[0] = 0xAA; 00533 send[1] = 0x07; 00534 send[2] = div1st; 00535 send[3] = div2nd; 00536 send[4] = 0x00; 00537 send[5] = 0x00; 00538 00539 if (!SENDFUNC(send, sizeof(send))) { 00540 return (ErrorNumber)SendRegisterTimeout; 00541 } 00542 00543 return (ErrorNumber)NoError; 00544 } 00545 00546 CameraC328::ErrorNumber CameraC328::sendReset(ResetType rt, bool specialReset) { 00547 char send[COMMAND_LENGTH]; 00548 send[0] = 0xAA; 00549 send[1] = 0x08; 00550 send[2] = (int)rt; 00551 send[3] = 0x00; 00552 send[4] = 0x00; 00553 send[5] = specialReset ? 0xff : 0x00; 00554 /* 00555 * Special reset : If the parameter is 0xFF, the command is a special Reset command and the firmware responds to it immediately. 00556 */ 00557 00558 if (!SENDFUNC(send, sizeof(send))) { 00559 return (ErrorNumber)SendRegisterTimeout; 00560 } 00561 00562 return (ErrorNumber)NoError; 00563 } 00564 00565 CameraC328::ErrorNumber CameraC328::sendPowerOff() { 00566 char send[COMMAND_LENGTH]; 00567 send[0] = 0xAA; 00568 send[1] = 0x09; 00569 send[2] = 0x00; 00570 send[3] = 0x00; 00571 send[4] = 0x00; 00572 send[5] = 0x00; 00573 00574 if (!SENDFUNC(send, sizeof(send))) { 00575 return (ErrorNumber)SendRegisterTimeout; 00576 } 00577 00578 return (ErrorNumber)NoError; 00579 } 00580 00581 CameraC328::ErrorNumber CameraC328::recvData(DataType *dt, uint32_t *length) { 00582 char recv[COMMAND_LENGTH]; 00583 if (!RECVFUNC(recv, sizeof(recv))) { 00584 return (ErrorNumber)UnexpectedReply; 00585 } 00586 if ((0xAA != recv[0]) || (0x0A != recv[1])) { 00587 return (ErrorNumber)UnexpectedReply; 00588 } 00589 *dt = (DataType)recv[2]; 00590 *length = (recv[5] << 16) | (recv[4] << 8) | (recv[3] << 0); 00591 return (ErrorNumber)NoError; 00592 } 00593 00594 CameraC328::ErrorNumber CameraC328::sendSync() { 00595 char send[COMMAND_LENGTH]; 00596 send[0] = 0xAA; 00597 send[1] = 0x0D; 00598 send[2] = 0x00; 00599 send[3] = 0x00; 00600 send[4] = 0x00; 00601 send[5] = 0x00; 00602 if (!SENDFUNC(send, sizeof(send))) { 00603 return (ErrorNumber)SendRegisterTimeout; 00604 } 00605 return (ErrorNumber)NoError; 00606 } 00607 00608 CameraC328::ErrorNumber CameraC328::recvSync() { 00609 char recv[COMMAND_LENGTH]; 00610 if (!RECVFUNC(recv, sizeof(recv))) { 00611 return (ErrorNumber)UnexpectedReply; 00612 } 00613 if ((0xAA != recv[0]) || (0x0D != recv[1])) { 00614 return (ErrorNumber)UnexpectedReply; 00615 } 00616 return (ErrorNumber)NoError; 00617 } 00618 00619 /** 00620 * Send ACK. 00621 * 00622 * @param commandId The command with that ID is acknowledged by this command. 00623 * @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. 00624 */ 00625 CameraC328::ErrorNumber CameraC328::sendAck(uint8_t commandId, uint16_t packageId) { 00626 char send[COMMAND_LENGTH]; 00627 send[0] = 0xAA; 00628 send[1] = 0x0E; 00629 send[2] = commandId; 00630 send[3] = 0x00; // ACK counter is not used. 00631 send[4] = (packageId >> 0) & 0xff; 00632 send[5] = (packageId >> 8) & 0xff; 00633 if (!SENDFUNC(send, sizeof(send))) { 00634 return (ErrorNumber)SendRegisterTimeout; 00635 } 00636 return (ErrorNumber)NoError; 00637 } 00638 00639 /** 00640 * Receive ACK or NCK. 00641 * 00642 * @return Error number. 00643 */ 00644 CameraC328::ErrorNumber CameraC328::recvAckOrNck() { 00645 char recv[COMMAND_LENGTH]; 00646 if (!RECVFUNC(recv, sizeof(recv))) { 00647 return (ErrorNumber)UnexpectedReply; 00648 } 00649 if ((0xAA == recv[0]) && (0x0E == recv[1])) { 00650 return (ErrorNumber)NoError; 00651 } 00652 if ((0xAA == recv[0]) && (0x0F == recv[1])) { 00653 return (ErrorNumber)recv[4]; 00654 } 00655 return (ErrorNumber)UnexpectedReply; 00656 } 00657 00658 /** 00659 * Send bytes to camera module. 00660 * 00661 * @param buf Pointer to the data buffer. 00662 * @param len Length of the data buffer. 00663 * 00664 * @return True if the data sended. 00665 */ 00666 bool CameraC328::sendBytes(char *buf, size_t len, int timeout_us) { 00667 for (uint32_t i = 0; i < (uint32_t)len; i++) { 00668 int cnt = 0; 00669 while (!serial.writeable()) { 00670 wait_us(1); 00671 cnt++; 00672 if (timeout_us < cnt) { 00673 return false; 00674 } 00675 } 00676 serial.putc(buf[i]); 00677 } 00678 return true; 00679 } 00680 00681 /** 00682 * Receive bytes from camera module. 00683 * 00684 * @param buf Pointer to the data buffer. 00685 * @param len Length of the data buffer. 00686 * 00687 * @return True if the data received. 00688 */ 00689 bool CameraC328::recvBytes(char *buf, size_t len, int timeout_us) { 00690 for (uint32_t i = 0; i < (uint32_t)len; i++) { 00691 int cnt = 0; 00692 while (!serial.readable()) { 00693 wait_us(1); 00694 cnt++; 00695 if (timeout_us < cnt) { 00696 return false; 00697 } 00698 } 00699 buf[i] = serial.getc(); 00700 } 00701 return true; 00702 } 00703 00704 /** 00705 * Wait received. 00706 * 00707 * @return True if the data received. 00708 */ 00709 bool CameraC328::waitRecv() { 00710 while (!serial.readable()) { 00711 } 00712 return true; 00713 } 00714 00715 /** 00716 * Wait idle state. 00717 */ 00718 bool CameraC328::waitIdle() { 00719 while (serial.readable()) { 00720 serial.getc(); 00721 } 00722 return true; 00723 }
Generated on Tue Jul 12 2022 19:24:07 by
1.7.2
