00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "l1394_dcccamera.h"
00019 #include "l1394_transaction.h"
00020 #include "l1394_card.h"
00021 #include "l1394_session.h"
00022
00023
00024 namespace L1394{
00025 using namespace internal;
00026 DccCamera::DccCamera(const u_int32_t node_id, const Card* parent)
00027 : Node(node_id, parent), Camera(this)
00028 {
00029 message->debugStream() << "DccCamera > create DccCamera " << endl ;
00030
00031 is_init = false;
00032 isoctx = NULL;
00033 setNodeType(_DccNode);
00034
00035 readGuid();
00036
00037 rom_info = new CsrRom(this);
00038 dcc_register = new DccRegister(this);
00039
00040
00041 setFrameSize(320*240*2);
00042 setFrameWidth(320);
00043 setFrameHeight(240);
00044 channel = 1;
00045 video_mode = DEVICE_320x240_YUV_422;
00046 frame_rate = DEVICE_FRAMES_15;
00047 frame_buffer= 3;
00048
00049 message->debugStream() << "DccCamera < create DccCamera " << endl ;
00050 addDevice(this);
00051 setName("DccCamera");
00052 }
00053
00054 DccCamera::~DccCamera()
00055 {
00056 getEventObject()->call(NODE_DESTROY);
00057
00058 delete rom_info;
00059 delete dcc_register;
00060 delete isoctx;
00061 }
00062
00063 Frame* DccCamera::getFrame()
00064 {
00065 MutexGuard m(mutex);
00066 if(isoctx)
00067 {
00068 switch(imode)
00069 {
00070 case DEVICE_ISO_RUN :
00071 if (!isSending())
00072 {
00073 message->warningStream() << "DccCamera > Camera not started" << endl;
00074 return NULL;
00075 }
00076 break;
00077
00078 case DEVICE_ISO_ONESHOT:
00079 shot();
00080 break;
00081
00082 default:
00083 break;
00084
00085 }
00086 return isoctx->getFrame();
00087 }
00088 else
00089 message->warningStream() << "DccCamera > No valid iso ctx" << endl;
00090 return NULL;
00091 }
00092
00093 int DccCamera::start()
00094 {
00095
00096 read(DCC_BASE + 0x614,&tmp_quadlet);
00097 tmp_quadlet.setBit(31, 1);
00098
00099 if (write(DCC_BASE + 0x614, tmp_quadlet) == L1394_SUCCESS);
00100 {
00101 setSending(true);
00102 return L1394_SUCCESS;
00103 }
00104 return L1394_FAILED;
00105
00106 }
00107
00108 int DccCamera::stop()
00109 {
00110 setSending(false);
00111 read(DCC_BASE + 0x614, &tmp_quadlet);
00112 tmp_quadlet.setBit(31, 0);
00113 write(DCC_BASE + 0x614, tmp_quadlet);
00114 if (isoctx)
00115 isoctx->flushQueue();
00116 return L1394_SUCCESS;
00117 }
00118
00119 void DccCamera::shot()
00120 {
00121 read(DCC_BASE + 0x61c,&tmp_quadlet);
00122
00123 if (tmp_quadlet.getBit(31) == 1) {
00124 internal::Transaction::delay(200);
00125 shot();
00126 } else {
00127 tmp_quadlet.setBit(31, 1);
00128 write(DCC_BASE + 0x61c,tmp_quadlet);
00129 }
00130 }
00131
00132 void DccCamera::multiShot(unsigned int i)
00133 {
00134 read(DCC_BASE + 0x614,&tmp_quadlet);
00135
00136
00137 read(DCC_BASE + 0x61c,&tmp_quadlet);
00138
00139 tmp_quadlet.setBit( 31, 0);
00140 tmp_quadlet.setBit( 30, 1);
00141
00142 tmp_quadlet.setBitRange(0, 15, i);
00143
00144 write(DCC_BASE + 0x61c,tmp_quadlet);
00145 }
00146
00147 int DccCamera::setParameter(const int buffercount, const int channel, const Isomode isomode, const Videomode videomode, const Framerate framerate)
00148 {
00149 MutexGuard m(mutex);
00150
00151
00152
00153
00154 frame_buffer = buffercount;
00155 imode = isomode;
00156 read(DCC_BASE + 0x400, &tmp_quadlet);
00157 switch(imode)
00158 {
00159 case DEVICE_ISO_ONESHOT :
00160 if (!tmp_quadlet.getBit(12))
00161 {
00162 message->warningStream() << "DccCamera > Camera does not support One-Shot. Reset to iso-run" << endl;
00163 imode = DEVICE_ISO_RUN;
00164 }
00165 break;
00166
00167 case DEVICE_ISO_MULTISHOT :
00168 if (!tmp_quadlet.getBit(11))
00169 {
00170 message->warningStream() << "DccCamera > Camera does not support Multi-Shot. Reset to iso-run" << endl;
00171 imode = DEVICE_ISO_RUN;
00172 }
00173 break;
00174 }
00175
00176 video_mode = videomode;
00177 frame_rate = framerate;
00178
00179 if (channel == FREE_ISO_CHANNEL)
00180 this->channel = 0;
00181
00182 return L1394_SUCCESS;
00183 }
00184 int DccCamera::init()
00185 {
00186
00187
00188
00189
00190
00191 MutexGuard m(mutex);
00192 Quadlet q;
00193 q.setBit(31,1);
00194 write(DCC_BASE + 0x0, q);
00195
00196 q.fromInt(0);
00197 write(DCC_BASE + 0x614, q);
00198
00199 if (!hasVideoFormat(video_mode))
00200 {
00201 message->warningStream() << "DccCamera > Video mode not supported" << endl;
00202 is_init = false;
00203 return L1394_FAILED;
00204 }
00205
00206 setVideoMode();
00207
00208 if (!hasFramerate(video_mode, frame_rate)) {
00209 message->warningStream() << "DccCamera > Framerate not supptorted with video_mode" << endl;
00210 is_init = false;
00211 return L1394_FAILED;
00212 }
00213
00214 setFramerate();
00215
00216 q.fromInt(0);
00217 q.setBitRange(28, 31, channel);
00218 q.setBitRange(24, 27, 0x2);
00219 write(DCC_BASE + 0x60c, q);
00220
00221 whiteBalance(0)->onePush(true);
00222
00223 if (isoctx != NULL) {
00224 delete isoctx;
00225 isoctx = 0;
00226 }
00227 if(imode != DEVICE_ISO_NO)
00228 {
00229
00230 const std::vector<std::string>& iso_dev = SSession::getInstance()->getIsoDevices();
00231
00232 if (iso_dev.size() < getCardID()) {
00233 message->errorStream() << "DccCamera > not enough video devices" << endl;
00234 return L1394_FAILED;
00235 }
00236
00237 isoctx = new DccIso(iso_dev[getCardID()].c_str());
00238
00239
00240 if( isoctx->setParameter(frame_buffer, channel, getFrameSize()) == L1394_FAILED)
00241 return L1394_FAILED;
00242 if( isoctx->startIsoListen() == L1394_FAILED )
00243 return L1394_FAILED;
00244 }
00245 is_init = true;
00246 return L1394_SUCCESS;
00247 }
00248
00249 void DccCamera::setVideoMode()
00250 {
00251 Quadlet q;
00252
00253 switch(video_mode)
00254 {
00255 case DEVICE_160x120_YUV_444:
00256 q.setBitRange(29, 31, 0);
00257 write(DCC_BASE + 0x604, q);
00258 setFrameWidth(160);
00259 setFrameHeight(120);
00260 setFrameSize(160 * 120 * 3);
00261 break;
00262
00263 case DEVICE_320x240_YUV_422:
00264 q.setBitRange(29, 31, 1);
00265 write(DCC_BASE + 0x604, q);
00266 setFrameWidth(320);
00267 setFrameHeight(240);
00268 setFrameSize(320 * 240 * 2);
00269 break;
00270
00271 case DEVICE_640x480_YUV_411:
00272 q.setBitRange(29, 31, 2);
00273 write(DCC_BASE + 0x604, q);
00274 setFrameWidth(640);
00275 setFrameHeight(480);
00276 setFrameSize(640 * 480 + (640*480)/2 );
00277 break;
00278
00279 case DEVICE_640x480_YUV_422:
00280 q.setBitRange(29, 31, 3);
00281 write(DCC_BASE + 0x604, q);
00282 setFrameWidth(640);
00283 setFrameHeight(480);
00284 setFrameSize(640 * 480 * 2);
00285 break;
00286
00287
00288 case DEVICE_640x480_RGB:
00289 q.setBitRange(29,31,4);
00290 write(DCC_BASE + 0x604, q);
00291 setFrameSize(640 * 480 * 3);
00292 setFrameWidth(640);
00293 setFrameHeight(480);
00294 break;
00295
00296 case DEVICE_640x480_MONO:
00297 q.setBitRange(29,31,5);
00298 write(DCC_BASE + 0x604, q);
00299 setFrameSize(640*480);
00300 setFrameWidth(640);
00301 setFrameHeight(480);
00302 break;
00303
00304 case DEVICE_800x600_YUV_422:
00305 q.setBitRange(29,31,0);
00306 write(DCC_BASE + 0x604, q);
00307 setFrameSize(800*600*2);
00308 setFrameWidth(800);
00309 setFrameHeight(600);
00310 break;
00311
00312 case DEVICE_800x600_RGB:
00313 q.setBitRange(29,31,1);
00314 write(DCC_BASE + 0x604, q);
00315 setFrameSize(800*600*3);
00316 setFrameWidth(800);
00317 setFrameHeight(600);
00318 break;
00319
00320 case DEVICE_800x600_MONO:
00321 q.setBitRange(29,31,2);
00322 write(DCC_BASE + 0x604, q);
00323 setFrameSize(800*600);
00324 setFrameWidth(800);
00325 setFrameHeight(600);
00326 break;
00327
00328 case DEVICE_1024x768_YUV_422:
00329 q.setBitRange(29,31,3);
00330 write(DCC_BASE + 0x604, q);
00331 setFrameSize(1024*768*2);
00332 setFrameWidth(1024);
00333 setFrameHeight(768);
00334 break;
00335
00336 case DEVICE_1024x768_RGB:
00337 q.setBitRange(29,31,4);
00338 write(DCC_BASE + 0x604, q);
00339 setFrameSize(1024*768*3);
00340 setFrameWidth(1024);
00341 setFrameHeight(768);
00342 break;
00343
00344 case DEVICE_1024x768_MONO:
00345 q.setBitRange(29,31,4);
00346 write(DCC_BASE + 0x604, q);
00347 setFrameSize(1024*768);
00348 setFrameWidth(1024);
00349 setFrameHeight(768);
00350 break;
00351
00352 case DEVICE_1280x960_YUV_422:
00353 q.setBitRange(29,31,0);
00354 write(DCC_BASE + 0x604, q);
00355 setFrameSize(1280*960*2);
00356 setFrameWidth(1280);
00357 setFrameHeight(960);
00358 break;
00359
00360 case DEVICE_1280x960_RGB:
00361 q.setBitRange(29,31,1);
00362 write(DCC_BASE + 0x604, q);
00363 setFrameSize(1280*960*3);
00364 setFrameWidth(1280);
00365 setFrameHeight(960);
00366 break;
00367
00368 case DEVICE_1280x960_MONO:
00369 q.setBitRange(29,31,2);
00370 write(DCC_BASE + 0x604, q);
00371 setFrameSize(1280*960);
00372 setFrameWidth(1280);
00373 setFrameHeight(960);
00374 break;
00375
00376 case DEVICE_1600x1200_YUV_422:
00377 q.setBitRange(29,31,3);
00378 write(DCC_BASE + 0x604, q);
00379 setFrameSize(1600*1200*2);
00380 setFrameWidth(1600);
00381 setFrameHeight(1200);
00382 break;
00383
00384 case DEVICE_1600x1200_RGB:
00385 q.setBitRange(29,31,4);
00386 write(DCC_BASE + 0x604, q);
00387 setFrameSize(1600*1200*3);
00388 setFrameWidth(1600);
00389 setFrameHeight(1200);
00390 break;
00391
00392 case DEVICE_1600x1200_MONO:
00393 q.setBitRange(29,31,5);
00394 write(DCC_BASE + 0x604, q);
00395 setFrameSize(1600*1200);
00396 setFrameWidth(1600);
00397 setFrameHeight(1200);
00398 break;
00399
00400 }
00401 q.fromInt(0);
00402 if (video_mode >= 0 && video_mode<=5 )
00403 write(DCC_BASE + 0x608, q);
00404 if (video_mode > 5 && video_mode<=11 )
00405 {
00406 q.setBitRange(29,31,1);
00407 write(DCC_BASE + 0x608, q);
00408 }
00409 if (video_mode > 11 && video_mode<=17 )
00410 {
00411 q.setBitRange(29,31,2);
00412 write(DCC_BASE + 0x608, q);
00413 }
00414 if (video_mode > 17)
00415 message->warningStream() << " DccCamera > Invalid video mode" <<endl;
00416 }
00417
00418 void DccCamera::setFramerate(const Framerate framerate)
00419 {
00420 frame_rate = framerate;
00421 setFramerate();
00422 }
00423
00424 void DccCamera::setFramerate()
00425 {
00426 Quadlet q;
00427 switch(frame_rate)
00428 {
00429 case DEVICE_FRAMES_3_75:
00430 q.setBitRange(29, 31, 1);
00431 write(DCC_BASE + 0x600, q);
00432 break;
00433
00434 case DEVICE_FRAMES_7_5:
00435 q.setBitRange(29, 31, 2);
00436 write(DCC_BASE + 0x600, q);
00437 break;
00438
00439 case DEVICE_FRAMES_15:
00440 q.setBitRange(29, 31, 3);
00441 write(DCC_BASE + 0x600, q);
00442 break;
00443
00444 case DEVICE_FRAMES_30:
00445 q.setBitRange(29, 31, 4);
00446 write(DCC_BASE + 0x600, q);
00447 break;
00448 default : message->warningStream() <<"DccCamera > Invalid framerate " << endl;
00449 }
00450
00451 }
00452
00453
00454 bool DccCamera::hasVideoFormat(const Videomode videomode)
00455 {
00456 Quadlet tmp_quadlet;
00457 switch(videomode)
00458 {
00459 case DEVICE_160x120_YUV_444: if (read(DCC_BASE + 0x180, &tmp_quadlet)) return tmp_quadlet.getBit(31); break;
00460 case DEVICE_320x240_YUV_422: if (read(DCC_BASE + 0x180, &tmp_quadlet)) return tmp_quadlet.getBit(30); break;
00461 case DEVICE_640x480_YUV_411: if (read(DCC_BASE + 0x180, &tmp_quadlet)) return tmp_quadlet.getBit(29); break;
00462 case DEVICE_640x480_YUV_422: if (read(DCC_BASE + 0x180, &tmp_quadlet)) return tmp_quadlet.getBit(28); break;
00463 case DEVICE_640x480_RGB: if (read(DCC_BASE + 0x180, &tmp_quadlet)) return tmp_quadlet.getBit(27); break;
00464 case DEVICE_640x480_MONO: if (read(DCC_BASE + 0x180, &tmp_quadlet)) return tmp_quadlet.getBit(26); break;
00465
00466 case DEVICE_800x600_YUV_422: if (read(DCC_BASE + 0x184, &tmp_quadlet)) return tmp_quadlet.getBit(31); break;
00467 case DEVICE_800x600_RGB: if (read(DCC_BASE + 0x184, &tmp_quadlet)) return tmp_quadlet.getBit(30); break;
00468 case DEVICE_800x600_MONO: if (read(DCC_BASE + 0x184, &tmp_quadlet)) return tmp_quadlet.getBit(29); break;
00469 case DEVICE_1024x768_YUV_422: if (read(DCC_BASE + 0x184, &tmp_quadlet)) return tmp_quadlet.getBit(28); break;
00470 case DEVICE_1024x768_RGB: if (read(DCC_BASE + 0x184, &tmp_quadlet)) return tmp_quadlet.getBit(27); break;
00471 case DEVICE_1024x768_MONO: if (read(DCC_BASE + 0x184, &tmp_quadlet)) return tmp_quadlet.getBit(26); break;
00472
00473 case DEVICE_1280x960_YUV_422: if (read(DCC_BASE + 0x188, &tmp_quadlet)) return tmp_quadlet.getBit(31); break;
00474 case DEVICE_1280x960_RGB: if (read(DCC_BASE + 0x188, &tmp_quadlet)) return tmp_quadlet.getBit(30); break;
00475 case DEVICE_1280x960_MONO: if (read(DCC_BASE + 0x188, &tmp_quadlet)) return tmp_quadlet.getBit(29); break;
00476 case DEVICE_1600x1200_YUV_422:if (read(DCC_BASE + 0x188, &tmp_quadlet)) return tmp_quadlet.getBit(28); break;
00477 case DEVICE_1600x1200_RGB: if (read(DCC_BASE + 0x188, &tmp_quadlet)) return tmp_quadlet.getBit(27); break;
00478 case DEVICE_1600x1200_MONO: if (read(DCC_BASE + 0x188, &tmp_quadlet)) return tmp_quadlet.getBit(26); break;
00479 default : return false;
00480 }
00481 return false;
00482 }
00483 bool DccCamera::hasFramerate(const Videomode mode,const Framerate framerate)
00484 {
00485 Quadlet tmp_quadlet;
00486 if (hasVideoFormat(mode)) {
00487 if (read(DCC_BASE + 0x200 + mode*0x04, &tmp_quadlet) == L1394_SUCCESS)
00488 return tmp_quadlet.getBit(31-framerate);
00489 return false;
00490 }
00491 return false;
00492 }
00493 }