CameraC328
Dependents: CameraC328_TestProgram CameraC328_Thresholding Camera_TestProgram_2015 Camera_TestProgram_2015 ... more
CameraC328.cpp@3:6d3150d4396a, 2010-06-29 (annotated)
- Committer:
- shintamainjp
- Date:
- Tue Jun 29 11:45:53 2010 +0000
- Revision:
- 3:6d3150d4396a
- Parent:
- 2:6a72fcad5c0a
- Child:
- 4:ad06342d4b84
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
shintamainjp | 3:6d3150d4396a | 1 | /** |
shintamainjp | 3:6d3150d4396a | 2 | * C328-7640 device driver class |
shintamainjp | 3:6d3150d4396a | 3 | * Reference documents: C328-7640 User Manual v3.0 2004.8.19 |
shintamainjp | 3:6d3150d4396a | 4 | * |
shintamainjp | 3:6d3150d4396a | 5 | * Version 0.0.1 |
shintamainjp | 3:6d3150d4396a | 6 | * |
shintamainjp | 3:6d3150d4396a | 7 | * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) |
shintamainjp | 3:6d3150d4396a | 8 | * shinta.main.jp@gmail.com |
shintamainjp | 3:6d3150d4396a | 9 | * http://shinta.main.jp/ |
shintamainjp | 3:6d3150d4396a | 10 | */ |
shintamainjp | 3:6d3150d4396a | 11 | |
shintamainjp | 2:6a72fcad5c0a | 12 | #include "CameraC328.h" |
shintamainjp | 2:6a72fcad5c0a | 13 | |
shintamainjp | 2:6a72fcad5c0a | 14 | #define SENDFUNC sendBytes |
shintamainjp | 2:6a72fcad5c0a | 15 | #define RECVFUNC recvBytes |
shintamainjp | 3:6d3150d4396a | 16 | #define WAITFUNC waitRecv |
shintamainjp | 2:6a72fcad5c0a | 17 | |
shintamainjp | 3:6d3150d4396a | 18 | CameraC328::CameraC328(PinName tx, PinName rx, Baud baud) : serial(tx, rx) { |
shintamainjp | 3:6d3150d4396a | 19 | serial.baud((int)baud); |
shintamainjp | 2:6a72fcad5c0a | 20 | } |
shintamainjp | 2:6a72fcad5c0a | 21 | |
shintamainjp | 2:6a72fcad5c0a | 22 | CameraC328::~CameraC328() { |
shintamainjp | 2:6a72fcad5c0a | 23 | } |
shintamainjp | 2:6a72fcad5c0a | 24 | |
shintamainjp | 2:6a72fcad5c0a | 25 | CameraC328::ErrorNumber CameraC328::sync() { |
shintamainjp | 2:6a72fcad5c0a | 26 | for (int i = 0; i < SYNCMAX; i++) { |
shintamainjp | 3:6d3150d4396a | 27 | if (NoError == sendSync()) { |
shintamainjp | 3:6d3150d4396a | 28 | if (NoError == recvAckOrNck()) { |
shintamainjp | 3:6d3150d4396a | 29 | if (NoError == recvSync()) { |
shintamainjp | 3:6d3150d4396a | 30 | if (NoError == sendAck(0x0D, 0x00)) { |
shintamainjp | 3:6d3150d4396a | 31 | /* |
shintamainjp | 3:6d3150d4396a | 32 | * After synchronization, the camera needs a little time for AEC and AGC to be stable. |
shintamainjp | 3:6d3150d4396a | 33 | * Users should wait for 1-2 seconds before capturing the first picture. |
shintamainjp | 3:6d3150d4396a | 34 | */ |
shintamainjp | 3:6d3150d4396a | 35 | wait(2); |
shintamainjp | 3:6d3150d4396a | 36 | return NoError; |
shintamainjp | 2:6a72fcad5c0a | 37 | } |
shintamainjp | 2:6a72fcad5c0a | 38 | } |
shintamainjp | 2:6a72fcad5c0a | 39 | } |
shintamainjp | 2:6a72fcad5c0a | 40 | } |
shintamainjp | 3:6d3150d4396a | 41 | wait_ms(50); |
shintamainjp | 2:6a72fcad5c0a | 42 | } |
shintamainjp | 2:6a72fcad5c0a | 43 | return UnexpectedReply; |
shintamainjp | 2:6a72fcad5c0a | 44 | } |
shintamainjp | 2:6a72fcad5c0a | 45 | |
shintamainjp | 2:6a72fcad5c0a | 46 | CameraC328::ErrorNumber CameraC328::init(ColorType ct, RawResolution rr, JpegResolution jr) { |
shintamainjp | 3:6d3150d4396a | 47 | ErrorNumber en; |
shintamainjp | 3:6d3150d4396a | 48 | |
shintamainjp | 3:6d3150d4396a | 49 | en = sendInitial(ct, rr, jr); |
shintamainjp | 3:6d3150d4396a | 50 | if (NoError != en) { |
shintamainjp | 3:6d3150d4396a | 51 | return en; |
shintamainjp | 3:6d3150d4396a | 52 | } |
shintamainjp | 3:6d3150d4396a | 53 | WAITFUNC(); |
shintamainjp | 3:6d3150d4396a | 54 | en = recvAckOrNck(); |
shintamainjp | 3:6d3150d4396a | 55 | if (NoError != en) { |
shintamainjp | 3:6d3150d4396a | 56 | return en; |
shintamainjp | 3:6d3150d4396a | 57 | } |
shintamainjp | 3:6d3150d4396a | 58 | |
shintamainjp | 3:6d3150d4396a | 59 | return (ErrorNumber)NoError; |
shintamainjp | 3:6d3150d4396a | 60 | } |
shintamainjp | 3:6d3150d4396a | 61 | |
shintamainjp | 3:6d3150d4396a | 62 | /** |
shintamainjp | 3:6d3150d4396a | 63 | * Get uncompressed snapshot picture (uncompressed snapshot picture) |
shintamainjp | 3:6d3150d4396a | 64 | * |
shintamainjp | 3:6d3150d4396a | 65 | * @param func Pointer to a callback function. |
shintamainjp | 3:6d3150d4396a | 66 | * @return Status of the error. |
shintamainjp | 3:6d3150d4396a | 67 | */ |
shintamainjp | 3:6d3150d4396a | 68 | CameraC328::ErrorNumber CameraC328::getUncompressedSnapshotPicture(void(*func)(size_t done, size_t total, char c)) { |
shintamainjp | 3:6d3150d4396a | 69 | ErrorNumber en; |
shintamainjp | 3:6d3150d4396a | 70 | |
shintamainjp | 3:6d3150d4396a | 71 | en = sendSnapshot(UncompressedPicture, 0); |
shintamainjp | 3:6d3150d4396a | 72 | if (NoError != en) { |
shintamainjp | 3:6d3150d4396a | 73 | return en; |
shintamainjp | 3:6d3150d4396a | 74 | } |
shintamainjp | 3:6d3150d4396a | 75 | WAITFUNC(); |
shintamainjp | 3:6d3150d4396a | 76 | en = recvAckOrNck(); |
shintamainjp | 3:6d3150d4396a | 77 | if (NoError != en) { |
shintamainjp | 3:6d3150d4396a | 78 | return en; |
shintamainjp | 3:6d3150d4396a | 79 | } |
shintamainjp | 3:6d3150d4396a | 80 | |
shintamainjp | 3:6d3150d4396a | 81 | en = sendGetPicture(SnapshotPicture); |
shintamainjp | 3:6d3150d4396a | 82 | if (NoError != en) { |
shintamainjp | 3:6d3150d4396a | 83 | return en; |
shintamainjp | 3:6d3150d4396a | 84 | } |
shintamainjp | 3:6d3150d4396a | 85 | WAITFUNC(); |
shintamainjp | 3:6d3150d4396a | 86 | en = recvAckOrNck(); |
shintamainjp | 3:6d3150d4396a | 87 | if (NoError != en) { |
shintamainjp | 3:6d3150d4396a | 88 | return en; |
shintamainjp | 3:6d3150d4396a | 89 | } |
shintamainjp | 3:6d3150d4396a | 90 | |
shintamainjp | 3:6d3150d4396a | 91 | /* |
shintamainjp | 3:6d3150d4396a | 92 | * image data |
shintamainjp | 3:6d3150d4396a | 93 | */ |
shintamainjp | 3:6d3150d4396a | 94 | DataType dt; |
shintamainjp | 3:6d3150d4396a | 95 | uint32_t length = 0; |
shintamainjp | 3:6d3150d4396a | 96 | WAITFUNC(); |
shintamainjp | 3:6d3150d4396a | 97 | en = recvData(&dt, &length); |
shintamainjp | 3:6d3150d4396a | 98 | if (NoError != en) { |
shintamainjp | 3:6d3150d4396a | 99 | return en; |
shintamainjp | 3:6d3150d4396a | 100 | } |
shintamainjp | 3:6d3150d4396a | 101 | size_t imgcnt = 0; |
shintamainjp | 3:6d3150d4396a | 102 | for (int i = 0; i < (int)length; i++) { |
shintamainjp | 3:6d3150d4396a | 103 | char c; |
shintamainjp | 3:6d3150d4396a | 104 | WAITFUNC(); |
shintamainjp | 3:6d3150d4396a | 105 | if (!RECVFUNC(&c, 1)) { |
shintamainjp | 3:6d3150d4396a | 106 | return (ErrorNumber)UnexpectedReply; |
shintamainjp | 3:6d3150d4396a | 107 | } |
shintamainjp | 3:6d3150d4396a | 108 | imgcnt++; |
shintamainjp | 3:6d3150d4396a | 109 | func(imgcnt, length, c); |
shintamainjp | 3:6d3150d4396a | 110 | } |
shintamainjp | 3:6d3150d4396a | 111 | |
shintamainjp | 3:6d3150d4396a | 112 | /* |
shintamainjp | 3:6d3150d4396a | 113 | * ACK |
shintamainjp | 3:6d3150d4396a | 114 | */ |
shintamainjp | 3:6d3150d4396a | 115 | en = sendAck(0x0A, 0x00); |
shintamainjp | 3:6d3150d4396a | 116 | if (NoError != en) { |
shintamainjp | 3:6d3150d4396a | 117 | return en; |
shintamainjp | 3:6d3150d4396a | 118 | } |
shintamainjp | 3:6d3150d4396a | 119 | |
shintamainjp | 3:6d3150d4396a | 120 | return (ErrorNumber)NoError; |
shintamainjp | 3:6d3150d4396a | 121 | } |
shintamainjp | 3:6d3150d4396a | 122 | |
shintamainjp | 3:6d3150d4396a | 123 | /** |
shintamainjp | 3:6d3150d4396a | 124 | * Get uncompressed snapshot picture (uncompressed snapshot picture) |
shintamainjp | 3:6d3150d4396a | 125 | * |
shintamainjp | 3:6d3150d4396a | 126 | * @param func Pointer to a callback function. |
shintamainjp | 3:6d3150d4396a | 127 | * @return Status of the error. |
shintamainjp | 3:6d3150d4396a | 128 | */ |
shintamainjp | 3:6d3150d4396a | 129 | CameraC328::ErrorNumber CameraC328::getUncompressedPreviewPicture(void(*func)(size_t done, size_t total, char c)) { |
shintamainjp | 3:6d3150d4396a | 130 | ErrorNumber en; |
shintamainjp | 3:6d3150d4396a | 131 | |
shintamainjp | 3:6d3150d4396a | 132 | en = sendGetPicture(PreviewPicture); |
shintamainjp | 3:6d3150d4396a | 133 | if (NoError != en) { |
shintamainjp | 3:6d3150d4396a | 134 | return en; |
shintamainjp | 3:6d3150d4396a | 135 | } |
shintamainjp | 3:6d3150d4396a | 136 | WAITFUNC(); |
shintamainjp | 3:6d3150d4396a | 137 | en = recvAckOrNck(); |
shintamainjp | 3:6d3150d4396a | 138 | if (NoError != en) { |
shintamainjp | 3:6d3150d4396a | 139 | return en; |
shintamainjp | 3:6d3150d4396a | 140 | } |
shintamainjp | 3:6d3150d4396a | 141 | |
shintamainjp | 3:6d3150d4396a | 142 | /* |
shintamainjp | 3:6d3150d4396a | 143 | * image data |
shintamainjp | 3:6d3150d4396a | 144 | */ |
shintamainjp | 3:6d3150d4396a | 145 | DataType dt; |
shintamainjp | 3:6d3150d4396a | 146 | uint32_t length = 0; |
shintamainjp | 3:6d3150d4396a | 147 | WAITFUNC(); |
shintamainjp | 3:6d3150d4396a | 148 | en = recvData(&dt, &length); |
shintamainjp | 3:6d3150d4396a | 149 | if (NoError != en) { |
shintamainjp | 3:6d3150d4396a | 150 | return en; |
shintamainjp | 3:6d3150d4396a | 151 | } |
shintamainjp | 3:6d3150d4396a | 152 | size_t imgcnt = 0; |
shintamainjp | 3:6d3150d4396a | 153 | for (int i = 0; i < (int)length; i++) { |
shintamainjp | 3:6d3150d4396a | 154 | char c; |
shintamainjp | 3:6d3150d4396a | 155 | WAITFUNC(); |
shintamainjp | 3:6d3150d4396a | 156 | if (!RECVFUNC(&c, 1)) { |
shintamainjp | 3:6d3150d4396a | 157 | return (ErrorNumber)UnexpectedReply; |
shintamainjp | 3:6d3150d4396a | 158 | } |
shintamainjp | 3:6d3150d4396a | 159 | imgcnt++; |
shintamainjp | 3:6d3150d4396a | 160 | func(imgcnt, length, c); |
shintamainjp | 3:6d3150d4396a | 161 | } |
shintamainjp | 3:6d3150d4396a | 162 | |
shintamainjp | 3:6d3150d4396a | 163 | /* |
shintamainjp | 3:6d3150d4396a | 164 | * ACK |
shintamainjp | 3:6d3150d4396a | 165 | */ |
shintamainjp | 3:6d3150d4396a | 166 | en = sendAck(0x0A, 0x00); |
shintamainjp | 3:6d3150d4396a | 167 | if (NoError != en) { |
shintamainjp | 3:6d3150d4396a | 168 | return en; |
shintamainjp | 3:6d3150d4396a | 169 | } |
shintamainjp | 3:6d3150d4396a | 170 | |
shintamainjp | 3:6d3150d4396a | 171 | return (ErrorNumber)NoError; |
shintamainjp | 3:6d3150d4396a | 172 | } |
shintamainjp | 3:6d3150d4396a | 173 | |
shintamainjp | 3:6d3150d4396a | 174 | CameraC328::ErrorNumber CameraC328::sendInitial(ColorType ct, RawResolution rr, JpegResolution jr) { |
shintamainjp | 2:6a72fcad5c0a | 175 | char send[COMMAND_LENGTH]; |
shintamainjp | 2:6a72fcad5c0a | 176 | |
shintamainjp | 2:6a72fcad5c0a | 177 | send[0] = 0xAA; |
shintamainjp | 2:6a72fcad5c0a | 178 | send[1] = 0x01; |
shintamainjp | 2:6a72fcad5c0a | 179 | send[2] = 0x00; |
shintamainjp | 2:6a72fcad5c0a | 180 | send[3] = (char)ct; |
shintamainjp | 2:6a72fcad5c0a | 181 | send[4] = (char)rr; |
shintamainjp | 2:6a72fcad5c0a | 182 | send[5] = (char)jr; |
shintamainjp | 2:6a72fcad5c0a | 183 | |
shintamainjp | 2:6a72fcad5c0a | 184 | if (!SENDFUNC(send, sizeof(send))) { |
shintamainjp | 2:6a72fcad5c0a | 185 | return (ErrorNumber)SendRegisterTimeout; |
shintamainjp | 2:6a72fcad5c0a | 186 | } |
shintamainjp | 2:6a72fcad5c0a | 187 | return (ErrorNumber)NoError; |
shintamainjp | 2:6a72fcad5c0a | 188 | } |
shintamainjp | 2:6a72fcad5c0a | 189 | |
shintamainjp | 3:6d3150d4396a | 190 | CameraC328::ErrorNumber CameraC328::sendGetPicture(PictureType pt) { |
shintamainjp | 2:6a72fcad5c0a | 191 | char send[COMMAND_LENGTH]; |
shintamainjp | 2:6a72fcad5c0a | 192 | |
shintamainjp | 2:6a72fcad5c0a | 193 | send[0] = 0xAA; |
shintamainjp | 3:6d3150d4396a | 194 | send[1] = 0x04; |
shintamainjp | 3:6d3150d4396a | 195 | send[2] = (char)pt; |
shintamainjp | 2:6a72fcad5c0a | 196 | send[3] = 0x00; |
shintamainjp | 2:6a72fcad5c0a | 197 | send[4] = 0x00; |
shintamainjp | 2:6a72fcad5c0a | 198 | send[5] = 0x00; |
shintamainjp | 2:6a72fcad5c0a | 199 | |
shintamainjp | 2:6a72fcad5c0a | 200 | if (!SENDFUNC(send, sizeof(send))) { |
shintamainjp | 2:6a72fcad5c0a | 201 | return (ErrorNumber)SendRegisterTimeout; |
shintamainjp | 2:6a72fcad5c0a | 202 | } |
shintamainjp | 3:6d3150d4396a | 203 | return (ErrorNumber)NoError; |
shintamainjp | 3:6d3150d4396a | 204 | } |
shintamainjp | 3:6d3150d4396a | 205 | |
shintamainjp | 3:6d3150d4396a | 206 | CameraC328::ErrorNumber CameraC328::sendSnapshot(SnapshotType st, uint16_t skipFrames) { |
shintamainjp | 3:6d3150d4396a | 207 | char send[COMMAND_LENGTH]; |
shintamainjp | 3:6d3150d4396a | 208 | send[0] = 0xAA; |
shintamainjp | 3:6d3150d4396a | 209 | send[1] = 0x05; |
shintamainjp | 3:6d3150d4396a | 210 | send[2] = (char)st; |
shintamainjp | 3:6d3150d4396a | 211 | send[3] = (skipFrames >> 0) & 0xff; |
shintamainjp | 3:6d3150d4396a | 212 | send[4] = (skipFrames >> 8) & 0xff; |
shintamainjp | 3:6d3150d4396a | 213 | send[5] = 0x00; |
shintamainjp | 3:6d3150d4396a | 214 | |
shintamainjp | 3:6d3150d4396a | 215 | if (!SENDFUNC(send, sizeof(send))) { |
shintamainjp | 3:6d3150d4396a | 216 | return (ErrorNumber)SendRegisterTimeout; |
shintamainjp | 3:6d3150d4396a | 217 | } |
shintamainjp | 3:6d3150d4396a | 218 | return (ErrorNumber)NoError; |
shintamainjp | 3:6d3150d4396a | 219 | } |
shintamainjp | 3:6d3150d4396a | 220 | |
shintamainjp | 3:6d3150d4396a | 221 | CameraC328::ErrorNumber CameraC328::sendSetPackageSize(uint16_t packageSize) { |
shintamainjp | 3:6d3150d4396a | 222 | char send[COMMAND_LENGTH]; |
shintamainjp | 3:6d3150d4396a | 223 | send[0] = 0xAA; |
shintamainjp | 3:6d3150d4396a | 224 | send[1] = 0x06; |
shintamainjp | 3:6d3150d4396a | 225 | send[2] = 0x08; |
shintamainjp | 3:6d3150d4396a | 226 | send[3] = (packageSize >> 0) & 0xff; |
shintamainjp | 3:6d3150d4396a | 227 | send[4] = (packageSize >> 8) & 0xff; |
shintamainjp | 3:6d3150d4396a | 228 | send[5] = 0x00; |
shintamainjp | 3:6d3150d4396a | 229 | |
shintamainjp | 3:6d3150d4396a | 230 | if (!SENDFUNC(send, sizeof(send))) { |
shintamainjp | 3:6d3150d4396a | 231 | return (ErrorNumber)SendRegisterTimeout; |
shintamainjp | 2:6a72fcad5c0a | 232 | } |
shintamainjp | 3:6d3150d4396a | 233 | return (ErrorNumber)NoError; |
shintamainjp | 3:6d3150d4396a | 234 | } |
shintamainjp | 3:6d3150d4396a | 235 | |
shintamainjp | 3:6d3150d4396a | 236 | CameraC328::ErrorNumber CameraC328::sendSetBaudrate(Baud baud) { |
shintamainjp | 3:6d3150d4396a | 237 | char send[COMMAND_LENGTH]; |
shintamainjp | 3:6d3150d4396a | 238 | |
shintamainjp | 3:6d3150d4396a | 239 | static struct baud_list { |
shintamainjp | 3:6d3150d4396a | 240 | Baud baud; |
shintamainjp | 3:6d3150d4396a | 241 | uint8_t div1st; |
shintamainjp | 3:6d3150d4396a | 242 | uint8_t div2nd; |
shintamainjp | 3:6d3150d4396a | 243 | } baudtable [] = { |
shintamainjp | 3:6d3150d4396a | 244 | { Baud7200, 0xff, 0x01 }, |
shintamainjp | 3:6d3150d4396a | 245 | { Baud9600, 0xbf, 0x01 }, |
shintamainjp | 3:6d3150d4396a | 246 | { Baud14400, 0x7f, 0x01 }, |
shintamainjp | 3:6d3150d4396a | 247 | { Baud19200, 0x5f, 0x01 }, |
shintamainjp | 3:6d3150d4396a | 248 | { Baud28800, 0x3f, 0x01 }, |
shintamainjp | 3:6d3150d4396a | 249 | { Baud38400, 0x2f, 0x01 }, |
shintamainjp | 3:6d3150d4396a | 250 | { Baud57600, 0x1f, 0x01 }, |
shintamainjp | 3:6d3150d4396a | 251 | { Baud115200, 0x0f, 0x01 } |
shintamainjp | 3:6d3150d4396a | 252 | }; |
shintamainjp | 3:6d3150d4396a | 253 | |
shintamainjp | 3:6d3150d4396a | 254 | uint8_t div1st = 0x00, div2nd = 0x00; |
shintamainjp | 3:6d3150d4396a | 255 | struct baud_list *p = &baudtable[0]; |
shintamainjp | 3:6d3150d4396a | 256 | for (int i = 0; i < sizeof(baudtable) / sizeof(baudtable[0]); i++) { |
shintamainjp | 3:6d3150d4396a | 257 | if (p->baud == baud) { |
shintamainjp | 3:6d3150d4396a | 258 | div1st = p->div1st; |
shintamainjp | 3:6d3150d4396a | 259 | div2nd = p->div2nd; |
shintamainjp | 3:6d3150d4396a | 260 | } |
shintamainjp | 3:6d3150d4396a | 261 | p++; |
shintamainjp | 2:6a72fcad5c0a | 262 | } |
shintamainjp | 2:6a72fcad5c0a | 263 | |
shintamainjp | 3:6d3150d4396a | 264 | send[0] = 0xAA; |
shintamainjp | 3:6d3150d4396a | 265 | send[1] = 0x07; |
shintamainjp | 3:6d3150d4396a | 266 | send[2] = div1st; |
shintamainjp | 3:6d3150d4396a | 267 | send[3] = div2nd; |
shintamainjp | 3:6d3150d4396a | 268 | send[4] = 0x00; |
shintamainjp | 3:6d3150d4396a | 269 | send[5] = 0x00; |
shintamainjp | 3:6d3150d4396a | 270 | |
shintamainjp | 3:6d3150d4396a | 271 | if (!SENDFUNC(send, sizeof(send))) { |
shintamainjp | 3:6d3150d4396a | 272 | return (ErrorNumber)SendRegisterTimeout; |
shintamainjp | 3:6d3150d4396a | 273 | } |
shintamainjp | 3:6d3150d4396a | 274 | |
shintamainjp | 3:6d3150d4396a | 275 | return (ErrorNumber)NoError; |
shintamainjp | 3:6d3150d4396a | 276 | } |
shintamainjp | 3:6d3150d4396a | 277 | |
shintamainjp | 3:6d3150d4396a | 278 | CameraC328::ErrorNumber CameraC328::sendReset(ResetType rt, bool specialReset) { |
shintamainjp | 3:6d3150d4396a | 279 | char send[COMMAND_LENGTH]; |
shintamainjp | 3:6d3150d4396a | 280 | send[0] = 0xAA; |
shintamainjp | 3:6d3150d4396a | 281 | send[1] = 0x08; |
shintamainjp | 3:6d3150d4396a | 282 | send[2] = (int)rt; |
shintamainjp | 3:6d3150d4396a | 283 | send[3] = 0x00; |
shintamainjp | 3:6d3150d4396a | 284 | send[4] = 0x00; |
shintamainjp | 3:6d3150d4396a | 285 | send[5] = specialReset ? 0xff : 0x00; |
shintamainjp | 2:6a72fcad5c0a | 286 | /* |
shintamainjp | 3:6d3150d4396a | 287 | * Special reset : If the parameter is 0xFF, the command is a special Reset command and the firmware responds to it immediately. |
shintamainjp | 2:6a72fcad5c0a | 288 | */ |
shintamainjp | 2:6a72fcad5c0a | 289 | |
shintamainjp | 3:6d3150d4396a | 290 | if (!SENDFUNC(send, sizeof(send))) { |
shintamainjp | 3:6d3150d4396a | 291 | return (ErrorNumber)SendRegisterTimeout; |
shintamainjp | 3:6d3150d4396a | 292 | } |
shintamainjp | 3:6d3150d4396a | 293 | |
shintamainjp | 3:6d3150d4396a | 294 | return (ErrorNumber)NoError; |
shintamainjp | 3:6d3150d4396a | 295 | } |
shintamainjp | 3:6d3150d4396a | 296 | |
shintamainjp | 3:6d3150d4396a | 297 | CameraC328::ErrorNumber CameraC328::sendPowerOff() { |
shintamainjp | 3:6d3150d4396a | 298 | char send[COMMAND_LENGTH]; |
shintamainjp | 2:6a72fcad5c0a | 299 | send[0] = 0xAA; |
shintamainjp | 3:6d3150d4396a | 300 | send[1] = 0x09; |
shintamainjp | 3:6d3150d4396a | 301 | send[2] = 0x00; |
shintamainjp | 2:6a72fcad5c0a | 302 | send[3] = 0x00; |
shintamainjp | 2:6a72fcad5c0a | 303 | send[4] = 0x00; |
shintamainjp | 2:6a72fcad5c0a | 304 | send[5] = 0x00; |
shintamainjp | 2:6a72fcad5c0a | 305 | |
shintamainjp | 2:6a72fcad5c0a | 306 | if (!SENDFUNC(send, sizeof(send))) { |
shintamainjp | 2:6a72fcad5c0a | 307 | return (ErrorNumber)SendRegisterTimeout; |
shintamainjp | 2:6a72fcad5c0a | 308 | } |
shintamainjp | 2:6a72fcad5c0a | 309 | |
shintamainjp | 3:6d3150d4396a | 310 | return (ErrorNumber)NoError; |
shintamainjp | 3:6d3150d4396a | 311 | } |
shintamainjp | 3:6d3150d4396a | 312 | |
shintamainjp | 3:6d3150d4396a | 313 | CameraC328::ErrorNumber CameraC328::recvData(DataType *dt, uint32_t *length) { |
shintamainjp | 3:6d3150d4396a | 314 | char recv[COMMAND_LENGTH]; |
shintamainjp | 2:6a72fcad5c0a | 315 | if (!RECVFUNC(recv, sizeof(recv))) { |
shintamainjp | 2:6a72fcad5c0a | 316 | return (ErrorNumber)UnexpectedReply; |
shintamainjp | 2:6a72fcad5c0a | 317 | } |
shintamainjp | 2:6a72fcad5c0a | 318 | if ((0xAA != recv[0]) || (0x0A != recv[1])) { |
shintamainjp | 3:6d3150d4396a | 319 | return (ErrorNumber)UnexpectedReply; |
shintamainjp | 2:6a72fcad5c0a | 320 | } |
shintamainjp | 3:6d3150d4396a | 321 | *dt = (DataType)recv[2]; |
shintamainjp | 3:6d3150d4396a | 322 | *length = (recv[5] << 16) | (recv[4] << 8) | (recv[3] << 0); |
shintamainjp | 3:6d3150d4396a | 323 | return (ErrorNumber)NoError; |
shintamainjp | 3:6d3150d4396a | 324 | } |
shintamainjp | 2:6a72fcad5c0a | 325 | |
shintamainjp | 3:6d3150d4396a | 326 | CameraC328::ErrorNumber CameraC328::sendSync() { |
shintamainjp | 3:6d3150d4396a | 327 | char send[COMMAND_LENGTH]; |
shintamainjp | 2:6a72fcad5c0a | 328 | send[0] = 0xAA; |
shintamainjp | 3:6d3150d4396a | 329 | send[1] = 0x0D; |
shintamainjp | 3:6d3150d4396a | 330 | send[2] = 0x00; |
shintamainjp | 2:6a72fcad5c0a | 331 | send[3] = 0x00; |
shintamainjp | 2:6a72fcad5c0a | 332 | send[4] = 0x00; |
shintamainjp | 2:6a72fcad5c0a | 333 | send[5] = 0x00; |
shintamainjp | 2:6a72fcad5c0a | 334 | if (!SENDFUNC(send, sizeof(send))) { |
shintamainjp | 2:6a72fcad5c0a | 335 | return (ErrorNumber)SendRegisterTimeout; |
shintamainjp | 2:6a72fcad5c0a | 336 | } |
shintamainjp | 3:6d3150d4396a | 337 | return (ErrorNumber)NoError; |
shintamainjp | 3:6d3150d4396a | 338 | } |
shintamainjp | 2:6a72fcad5c0a | 339 | |
shintamainjp | 3:6d3150d4396a | 340 | CameraC328::ErrorNumber CameraC328::recvSync() { |
shintamainjp | 3:6d3150d4396a | 341 | char recv[COMMAND_LENGTH]; |
shintamainjp | 3:6d3150d4396a | 342 | if (!RECVFUNC(recv, sizeof(recv))) { |
shintamainjp | 3:6d3150d4396a | 343 | return (ErrorNumber)UnexpectedReply; |
shintamainjp | 3:6d3150d4396a | 344 | } |
shintamainjp | 3:6d3150d4396a | 345 | if ((0xAA != recv[0]) || (0x0D != recv[1])) { |
shintamainjp | 3:6d3150d4396a | 346 | return (ErrorNumber)UnexpectedReply; |
shintamainjp | 3:6d3150d4396a | 347 | } |
shintamainjp | 2:6a72fcad5c0a | 348 | return (ErrorNumber)NoError; |
shintamainjp | 2:6a72fcad5c0a | 349 | } |
shintamainjp | 2:6a72fcad5c0a | 350 | |
shintamainjp | 2:6a72fcad5c0a | 351 | /** |
shintamainjp | 3:6d3150d4396a | 352 | * Send ACK. |
shintamainjp | 3:6d3150d4396a | 353 | * |
shintamainjp | 3:6d3150d4396a | 354 | * @param commandId The command with that ID is acknowledged by this command. |
shintamainjp | 3:6d3150d4396a | 355 | * @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. |
shintamainjp | 3:6d3150d4396a | 356 | */ |
shintamainjp | 3:6d3150d4396a | 357 | CameraC328::ErrorNumber CameraC328::sendAck(uint8_t commandId, uint16_t packageId) { |
shintamainjp | 3:6d3150d4396a | 358 | char send[COMMAND_LENGTH]; |
shintamainjp | 3:6d3150d4396a | 359 | send[0] = 0xAA; |
shintamainjp | 3:6d3150d4396a | 360 | send[1] = 0x0E; |
shintamainjp | 3:6d3150d4396a | 361 | send[2] = commandId; |
shintamainjp | 3:6d3150d4396a | 362 | send[3] = 0x00; // ACK counter is not used. |
shintamainjp | 3:6d3150d4396a | 363 | send[4] = (packageId >> 0) & 0xff; |
shintamainjp | 3:6d3150d4396a | 364 | send[5] = (packageId >> 8) & 0xff; |
shintamainjp | 3:6d3150d4396a | 365 | if (!SENDFUNC(send, sizeof(send))) { |
shintamainjp | 3:6d3150d4396a | 366 | return (ErrorNumber)SendRegisterTimeout; |
shintamainjp | 3:6d3150d4396a | 367 | } |
shintamainjp | 3:6d3150d4396a | 368 | return (ErrorNumber)NoError; |
shintamainjp | 3:6d3150d4396a | 369 | } |
shintamainjp | 3:6d3150d4396a | 370 | |
shintamainjp | 3:6d3150d4396a | 371 | /** |
shintamainjp | 3:6d3150d4396a | 372 | * Receive ACK or NCK. |
shintamainjp | 3:6d3150d4396a | 373 | * |
shintamainjp | 3:6d3150d4396a | 374 | * @return Error number. |
shintamainjp | 3:6d3150d4396a | 375 | */ |
shintamainjp | 3:6d3150d4396a | 376 | CameraC328::ErrorNumber CameraC328::recvAckOrNck() { |
shintamainjp | 3:6d3150d4396a | 377 | char recv[COMMAND_LENGTH]; |
shintamainjp | 3:6d3150d4396a | 378 | if (!RECVFUNC(recv, sizeof(recv))) { |
shintamainjp | 3:6d3150d4396a | 379 | return (ErrorNumber)UnexpectedReply; |
shintamainjp | 3:6d3150d4396a | 380 | } |
shintamainjp | 3:6d3150d4396a | 381 | if ((0xAA == recv[0]) && (0x0E == recv[1])) { |
shintamainjp | 3:6d3150d4396a | 382 | return (ErrorNumber)NoError; |
shintamainjp | 3:6d3150d4396a | 383 | } |
shintamainjp | 3:6d3150d4396a | 384 | if ((0xAA == recv[0]) && (0x0F == recv[1])) { |
shintamainjp | 3:6d3150d4396a | 385 | return (ErrorNumber)recv[4]; |
shintamainjp | 3:6d3150d4396a | 386 | } |
shintamainjp | 3:6d3150d4396a | 387 | return (ErrorNumber)UnexpectedReply; |
shintamainjp | 3:6d3150d4396a | 388 | } |
shintamainjp | 3:6d3150d4396a | 389 | |
shintamainjp | 3:6d3150d4396a | 390 | /** |
shintamainjp | 2:6a72fcad5c0a | 391 | * Send bytes to camera module. |
shintamainjp | 2:6a72fcad5c0a | 392 | * |
shintamainjp | 2:6a72fcad5c0a | 393 | * @param buf Pointer to the data buffer. |
shintamainjp | 2:6a72fcad5c0a | 394 | * @param len Length of the data buffer. |
shintamainjp | 2:6a72fcad5c0a | 395 | * |
shintamainjp | 2:6a72fcad5c0a | 396 | * @return True if the data sended. |
shintamainjp | 2:6a72fcad5c0a | 397 | */ |
shintamainjp | 3:6d3150d4396a | 398 | bool CameraC328::sendBytes(char *buf, size_t len, int timeout_us) { |
shintamainjp | 2:6a72fcad5c0a | 399 | for (uint32_t i = 0; i < (uint32_t)len; i++) { |
shintamainjp | 2:6a72fcad5c0a | 400 | int cnt = 0; |
shintamainjp | 2:6a72fcad5c0a | 401 | while (!serial.writeable()) { |
shintamainjp | 3:6d3150d4396a | 402 | wait_us(1); |
shintamainjp | 2:6a72fcad5c0a | 403 | cnt++; |
shintamainjp | 3:6d3150d4396a | 404 | if (timeout_us < cnt) { |
shintamainjp | 2:6a72fcad5c0a | 405 | return false; |
shintamainjp | 2:6a72fcad5c0a | 406 | } |
shintamainjp | 2:6a72fcad5c0a | 407 | } |
shintamainjp | 2:6a72fcad5c0a | 408 | serial.putc(buf[i]); |
shintamainjp | 2:6a72fcad5c0a | 409 | } |
shintamainjp | 2:6a72fcad5c0a | 410 | return true; |
shintamainjp | 2:6a72fcad5c0a | 411 | } |
shintamainjp | 2:6a72fcad5c0a | 412 | |
shintamainjp | 2:6a72fcad5c0a | 413 | /** |
shintamainjp | 2:6a72fcad5c0a | 414 | * Receive bytes from camera module. |
shintamainjp | 2:6a72fcad5c0a | 415 | * |
shintamainjp | 2:6a72fcad5c0a | 416 | * @param buf Pointer to the data buffer. |
shintamainjp | 2:6a72fcad5c0a | 417 | * @param len Length of the data buffer. |
shintamainjp | 2:6a72fcad5c0a | 418 | * |
shintamainjp | 2:6a72fcad5c0a | 419 | * @return True if the data received. |
shintamainjp | 2:6a72fcad5c0a | 420 | */ |
shintamainjp | 3:6d3150d4396a | 421 | bool CameraC328::recvBytes(char *buf, size_t len, int timeout_us) { |
shintamainjp | 2:6a72fcad5c0a | 422 | for (uint32_t i = 0; i < (uint32_t)len; i++) { |
shintamainjp | 2:6a72fcad5c0a | 423 | int cnt = 0; |
shintamainjp | 2:6a72fcad5c0a | 424 | while (!serial.readable()) { |
shintamainjp | 3:6d3150d4396a | 425 | wait_us(1); |
shintamainjp | 2:6a72fcad5c0a | 426 | cnt++; |
shintamainjp | 3:6d3150d4396a | 427 | if (timeout_us < cnt) { |
shintamainjp | 2:6a72fcad5c0a | 428 | return false; |
shintamainjp | 2:6a72fcad5c0a | 429 | } |
shintamainjp | 2:6a72fcad5c0a | 430 | } |
shintamainjp | 2:6a72fcad5c0a | 431 | buf[i] = serial.getc(); |
shintamainjp | 2:6a72fcad5c0a | 432 | } |
shintamainjp | 2:6a72fcad5c0a | 433 | return true; |
shintamainjp | 2:6a72fcad5c0a | 434 | } |
shintamainjp | 3:6d3150d4396a | 435 | |
shintamainjp | 3:6d3150d4396a | 436 | /** |
shintamainjp | 3:6d3150d4396a | 437 | * Wait received. |
shintamainjp | 3:6d3150d4396a | 438 | * |
shintamainjp | 3:6d3150d4396a | 439 | * @return True if the data received. |
shintamainjp | 3:6d3150d4396a | 440 | */ |
shintamainjp | 3:6d3150d4396a | 441 | bool CameraC328::waitRecv() { |
shintamainjp | 3:6d3150d4396a | 442 | while (!serial.readable()) { |
shintamainjp | 3:6d3150d4396a | 443 | } |
shintamainjp | 3:6d3150d4396a | 444 | return true; |
shintamainjp | 3:6d3150d4396a | 445 | } |