FrelonCamera.cpp 16.4 KB
Newer Older
1
#include "FrelonCamera.h"
2
#include "RegEx.h"
3
#include "MiscUtils.h"
4
#include <sstream>
5

6
using namespace lima;
7
8
9
using namespace lima::Frelon;
using namespace std;

10
11
12
const double Camera::HorzBinChangeTime = 2.0;
const double Camera::MaxReadoutTime    = 0.7;

ahoms's avatar
ahoms committed
13

14
15
16
Camera::Camera(Espia::SerialLine& espia_ser_line)
	: m_ser_line(espia_ser_line)
{
17
18
	DEB_CONSTRUCTOR();

19
	m_trig_mode = IntTrig;
20
21
22
23
24

	string ver;
	getVersion(ver);
	int ser_nb;
	getSerialNb(ser_nb);
25
26
}

27
28
29
30
31
32
Camera::~Camera()
{
	DEB_DESTRUCTOR();

}

33
34
35
36
37
SerialLine& Camera::getSerialLine()
{
	return m_ser_line;
}

38
39
Espia::Dev& Camera::getEspiaDev()
{
40
	Espia::SerialLine& ser_line = m_ser_line.getEspiaSerialLine();
41
42
43
44
	Espia::Dev& dev = ser_line.getDev();
	return dev;
}

45
46
void Camera::sendCmd(Cmd cmd)
{
47
48
	DEB_MEMBER_FUNCT();
	const string& cmd_str = CmdStrMap[cmd];
49
	DEB_PARAM() << DEB_VAR2(cmd, cmd_str);
50
51
52
53
54
	if (cmd_str.empty()) {
		DEB_ERROR() << "Invalid command cmd=" << cmd;
		throw LIMA_HW_EXC(InvalidValue, "Invalid command");
	}

55
	string resp;
56
	m_ser_line.sendFmtCmd(cmd_str, resp);
57
58
59
60
}

void Camera::writeRegister(Reg reg, int val)
{
61
62
	DEB_MEMBER_FUNCT();
	const string& reg_str = RegStrMap[reg];
63
	DEB_PARAM() << DEB_VAR3(reg, reg_str, val);
64
65
66
67
68
	if (reg_str.empty()) {
		DEB_ERROR() << "Invalid register reg=" << reg;
		throw LIMA_HW_EXC(InvalidValue, "Invalid register");
	}

69
	ostringstream cmd;
70
	cmd << reg_str << val;
71
72
73
74
75
76
	string resp;
	m_ser_line.sendFmtCmd(cmd.str(), resp);
}

void Camera::readRegister(Reg reg, int& val)
{
77
	DEB_MEMBER_FUNCT();
78

79
	const string& reg_str = RegStrMap[reg];
80
	DEB_PARAM() << DEB_VAR2(reg, reg_str);
81
82
83
84
85
86
87
	if (reg_str.empty()) {
		DEB_ERROR() << "Invalid register reg=" << reg;
		throw LIMA_HW_EXC(InvalidValue, "Invalid register");
	}

	string resp;
	m_ser_line.sendFmtCmd(reg_str + "?", resp);
88
89
	istringstream is(resp);
	is >> val;
90
91

	DEB_RETURN() << DEB_VAR1(val);
92
93
94
95
}

void Camera::hardReset()
{
96
	DEB_MEMBER_FUNCT();
97
98
99
	Espia::Dev& dev = getEspiaDev();
	dev.resetLink();

100
	DEB_TRACE() << "Reseting the camera";
101
102
103
104
105
	sendCmd(Reset);
}

void Camera::getVersion(string& ver)
{
106
	DEB_MEMBER_FUNCT();
107
108
	string cmd = RegStrMap[Version] + "?";
	m_ser_line.sendFmtCmd(cmd, ver);
109
	DEB_RETURN() << DEB_VAR1(ver);
110
}
ahoms's avatar
ahoms committed
111
112
113

void Camera::getComplexSerialNb(int& complex_ser_nb)
{
114
	DEB_MEMBER_FUNCT();
ahoms's avatar
ahoms committed
115
	readRegister(CompSerNb, complex_ser_nb);
116
	DEB_RETURN() << DEB_VAR1(DEB_HEX(complex_ser_nb));
ahoms's avatar
ahoms committed
117
118
119
120
}

void Camera::getSerialNbParam(SerNbParam param, int& val)
{
121
122
	DEB_MEMBER_FUNCT();
	DEB_PARAM() << DEB_VAR1(DEB_HEX(param));
ahoms's avatar
ahoms committed
123
124
125
126
127
	int complex_ser_nb;
	getComplexSerialNb(complex_ser_nb);
	val = complex_ser_nb & int(param);
}

128
129
void Camera::getSerialNb(int& ser_nb)
{
130
	DEB_MEMBER_FUNCT();
131
	getSerialNbParam(SerNb, ser_nb);
132
	DEB_RETURN() << DEB_VAR1(ser_nb);
133
134
135
}

void Camera::isFrelon2k16(bool& is_frelon_2k16)
ahoms's avatar
ahoms committed
136
{
137
	DEB_MEMBER_FUNCT();
ahoms's avatar
ahoms committed
138
139
	int frelon_2k16;
	getSerialNbParam(F2k16, frelon_2k16);
140
	is_frelon_2k16 = bool(frelon_2k16);
141
	DEB_RETURN() << DEB_VAR1(is_frelon_2k16);
142
143
144
145
}

void Camera::isFrelon4M(bool& is_frelon_4m)
{
146
	DEB_MEMBER_FUNCT();
147
148
149
	int f4m;
	getSerialNbParam(F4M, f4m);
	is_frelon_4m = bool(f4m);
150
	DEB_RETURN() << DEB_VAR1(is_frelon_4m);
151
152
153
154
}

void Camera::hasTaper(bool& has_taper)
{
155
	DEB_MEMBER_FUNCT();
156
157
158
	int taper;
	getSerialNbParam(Taper, taper);
	has_taper = bool(taper);
159
	DEB_RETURN() << DEB_VAR1(has_taper);
ahoms's avatar
ahoms committed
160
161
162
163
}

void Camera::setChanMode(int chan_mode)
{
164
165
	DEB_MEMBER_FUNCT();
	DEB_PARAM() << DEB_VAR1(chan_mode);
ahoms's avatar
ahoms committed
166
167
168
169
170
	writeRegister(ChanMode, chan_mode);
}

void Camera::getChanMode(int& chan_mode)
{
171
	DEB_MEMBER_FUNCT();
ahoms's avatar
ahoms committed
172
	readRegister(ChanMode, chan_mode);
173
	DEB_RETURN() << DEB_VAR1(chan_mode);
ahoms's avatar
ahoms committed
174
175
176
177
}

void Camera::getBaseChanMode(FrameTransferMode ftm, int& base_chan_mode)
{
178
	DEB_MEMBER_FUNCT();
ahoms's avatar
ahoms committed
179
	base_chan_mode = FTMChanRangeMap[ftm].first;
180
	DEB_RETURN() << DEB_VAR1(base_chan_mode);
ahoms's avatar
ahoms committed
181
182
183
184
185
}

void Camera::getInputChanMode(FrameTransferMode ftm, InputChan input_chan,
			      int& chan_mode)
{
186
187
188
	DEB_MEMBER_FUNCT();
	DEB_PARAM() << DEB_VAR2(ftm, DEB_HEX(input_chan));

ahoms's avatar
ahoms committed
189
190
191
192
193
194
195
	getBaseChanMode(ftm, chan_mode);
	const InputChanList& chan_list = FTMInputChanListMap[ftm];
	InputChanList::const_iterator it;
	it = find(chan_list.begin(), chan_list.end(), input_chan);
	if (it == chan_list.end())
		throw LIMA_HW_EXC(InvalidValue, "Invalid input channel");
	chan_mode += it - chan_list.begin();
196
197

	DEB_RETURN() << DEB_VAR1(chan_mode);
ahoms's avatar
ahoms committed
198
199
200
201
}

void Camera::setInputChan(InputChan input_chan)
{
202
203
204
	DEB_MEMBER_FUNCT();
	DEB_PARAM() << DEB_VAR1(DEB_HEX(input_chan));

ahoms's avatar
ahoms committed
205
206
207
208
209
210
211
212
213
	FrameTransferMode ftm;
	getFrameTransferMode(ftm);
	int chan_mode;
	getInputChanMode(ftm, input_chan, chan_mode);
	setChanMode(chan_mode);
}

void Camera::getInputChan(InputChan& input_chan)
{
214
215
	DEB_MEMBER_FUNCT();

ahoms's avatar
ahoms committed
216
217
218
219
220
221
	FrameTransferMode ftm;
	getFrameTransferMode(ftm);
	int chan_mode, base_chan_mode;
	getChanMode(chan_mode);
	getBaseChanMode(ftm, base_chan_mode);
	input_chan = FTMInputChanListMap[ftm][chan_mode - base_chan_mode];
222
223

	DEB_RETURN() << DEB_VAR1(DEB_HEX(input_chan));
ahoms's avatar
ahoms committed
224
225
226
227
}

void Camera::setFrameTransferMode(FrameTransferMode ftm)
{
228
229
230
	DEB_MEMBER_FUNCT();
	DEB_PARAM() << DEB_VAR1(ftm);
	
ahoms's avatar
ahoms committed
231
232
233
234
235
236
237
238
239
	InputChan input_chan;
	getInputChan(input_chan);
	int chan_mode;
	getInputChanMode(ftm, input_chan, chan_mode);
	setChanMode(chan_mode);
}

void Camera::getFrameTransferMode(FrameTransferMode& ftm)
{
240
241
	DEB_MEMBER_FUNCT();

ahoms's avatar
ahoms committed
242
243
244
245
246
247
248
	int chan_mode;
	getChanMode(chan_mode);

	FTMChanRangeMapType::const_iterator it, end = FTMChanRangeMap.end();
	for (it = FTMChanRangeMap.begin(); it != end; ++it) {
		ftm = it->first;
		const ChanRange& range = it->second;
249
250
		if ((chan_mode >= range.first) && (chan_mode < range.second)) {
			DEB_RETURN() << DEB_VAR1(ftm);
ahoms's avatar
ahoms committed
251
			return;
252
		}
ahoms's avatar
ahoms committed
253
254
255
256
257
258
259
	}

	throw LIMA_HW_EXC(Error, "Invalid chan mode");
}

void Camera::getFrameDim(FrameDim& frame_dim)
{
260
261
	DEB_MEMBER_FUNCT();

ahoms's avatar
ahoms committed
262
263
264
265
266
	frame_dim = MaxFrameDim;
	FrameTransferMode ftm;
	getFrameTransferMode(ftm);
	if (ftm == FTM)
		frame_dim /= Point(1, 2);
267
268

	DEB_RETURN() << DEB_VAR1(frame_dim);
ahoms's avatar
ahoms committed
269
270
271
272
}

void Camera::setFlipMode(int flip_mode)
{
273
274
	DEB_MEMBER_FUNCT();
	DEB_PARAM() << DEB_VAR1(flip_mode);
ahoms's avatar
ahoms committed
275
276
277
278
279
	writeRegister(Flip, flip_mode);
}

void Camera::getFlipMode(int& flip_mode)
{
280
	DEB_MEMBER_FUNCT();
ahoms's avatar
ahoms committed
281
	readRegister(Flip, flip_mode);
282
	DEB_RETURN() << DEB_VAR1(flip_mode);
ahoms's avatar
ahoms committed
283
284
285
286
}

void Camera::setFlip(const Point& flip)
{
287
288
	DEB_MEMBER_FUNCT();
	DEB_PARAM() << DEB_VAR1(flip);
ahoms's avatar
ahoms committed
289
290
291
292
293
294
	int flip_mode = (bool(flip.x) << 1) | (bool(flip.y) << 0);
	setFlipMode(flip_mode);
}

void Camera::getFlip(Point& flip)
{
295
296
	DEB_MEMBER_FUNCT();

ahoms's avatar
ahoms committed
297
298
299
300
	int flip_mode;
	getFlipMode(flip_mode);
	flip.x = (flip_mode >> 1) & 1;
	flip.y = (flip_mode >> 0) & 1;
301
302

	DEB_RETURN() << DEB_VAR1(flip);
ahoms's avatar
ahoms committed
303
304
}

305
306
void Camera::checkBin(Bin& bin)
{
307
308
309
	DEB_MEMBER_FUNCT();
	DEB_PARAM() << DEB_VAR1(bin);
	
310
311
312
	int bin_x = min(bin.getX(), int(MaxBinX));
	int bin_y = min(bin.getY(), int(MaxBinY));
	bin = Bin(bin_x, bin_y);
313
314

	DEB_RETURN() << DEB_VAR1(bin);
315
316
}

ahoms's avatar
ahoms committed
317
318
void Camera::setBin(const Bin& bin)
{
319
320
321
322
323
	DEB_MEMBER_FUNCT();
	DEB_PARAM() << DEB_VAR1(bin);
	
	if ((bin.getX() > 8) || (bin.getY() > 1024)) {
		DEB_ERROR() << "Invalid bin: " << bin << ". Must be <= 8x1024";
324
		throw LIMA_HW_EXC(InvalidValue, "Bin must be <= 8x1024");
325
	}
326

ahoms's avatar
ahoms committed
327
328
	Bin curr_bin;
	getBin(curr_bin);
329
330
	DEB_TRACE() << DEB_VAR1(curr_bin);
	if (bin == curr_bin) 
ahoms's avatar
ahoms committed
331
332
		return;

333
	DEB_TRACE() << "Reseting Roi";
334
335
336
	Roi roi;
	setRoi(roi);

ahoms's avatar
ahoms committed
337
	writeRegister(BinHorz, bin.getX());
338
	DEB_TRACE() << "Sleeping " << DEB_VAR1(HorzBinChangeTime);
339
	Sleep(HorzBinChangeTime);
ahoms's avatar
ahoms committed
340
341
342
343
344
	writeRegister(BinVert, bin.getY());
}

void Camera::getBin(Bin& bin)
{
345
	DEB_MEMBER_FUNCT();
ahoms's avatar
ahoms committed
346
347
348
349
	int bin_x, bin_y;
	readRegister(BinHorz, bin_x);
	readRegister(BinVert, bin_y);
	bin = Bin(bin_x, bin_y);
350
	DEB_RETURN() << DEB_VAR1(bin);
ahoms's avatar
ahoms committed
351
352
353
354
}

void Camera::setRoiMode(RoiMode roi_mode)
{
355
356
357
	DEB_MEMBER_FUNCT();
	DEB_PARAM() << DEB_VAR1(roi_mode);

ahoms's avatar
ahoms committed
358
359
360
	bool roi_hw   = (roi_mode == Slow) || (roi_mode == Fast);
	bool roi_fast = (roi_mode == Fast) || (roi_mode == Kinetic);
	bool roi_kin  = (roi_mode == Kinetic);
361
	DEB_TRACE() << DEB_VAR3(roi_hw, roi_fast, roi_kin);
ahoms's avatar
ahoms committed
362
363
364
365
366
367
368
369

	writeRegister(RoiEnable,  roi_hw);
	writeRegister(RoiFast,    roi_fast);
	writeRegister(RoiKinetic, roi_kin);
}

void Camera::getRoiMode(RoiMode& roi_mode)
{
370
371
	DEB_MEMBER_FUNCT();

ahoms's avatar
ahoms committed
372
373
374
375
	int roi_hw, roi_fast, roi_kin;
	readRegister(RoiEnable,  roi_hw);
	readRegister(RoiFast,    roi_fast);
	readRegister(RoiKinetic, roi_kin);
376
	DEB_TRACE() << DEB_VAR3(roi_hw, roi_fast, roi_kin);
ahoms's avatar
ahoms committed
377
378
379
380
381
382
383
384
385

	if (roi_fast && roi_kin)
		roi_mode = Kinetic;
	else if (roi_fast && roi_hw)
		roi_mode = Fast;
	else if (roi_hw)
		roi_mode = Slow;
	else
		roi_mode = None;
386
387

	DEB_RETURN() << DEB_VAR1(roi_mode);
ahoms's avatar
ahoms committed
388
389
390
391
}

void Camera::getMirror(Point& mirror)
{
392
	DEB_MEMBER_FUNCT();
ahoms's avatar
ahoms committed
393
394
	mirror.x = isChanActive(Chan12) || isChanActive(Chan34);
	mirror.y = isChanActive(Chan13) || isChanActive(Chan24);
395
	DEB_RETURN() << DEB_VAR1(mirror);
ahoms's avatar
ahoms committed
396
397
398
399
}

void Camera::getNbChan(Point& nb_chan)
{
400
	DEB_MEMBER_FUNCT();
ahoms's avatar
ahoms committed
401
402
	getMirror(nb_chan);
	nb_chan += 1;
403
	DEB_RETURN() << DEB_VAR1(nb_chan);
ahoms's avatar
ahoms committed
404
405
406
407
}

void Camera::getCcdSize(Size& ccd_size)
{
408
	DEB_MEMBER_FUNCT();
ahoms's avatar
ahoms committed
409
410
411
	FrameDim frame_dim;
	getFrameDim(frame_dim);
	ccd_size = frame_dim.getSize();
412
	DEB_RETURN() << DEB_VAR1(ccd_size);
ahoms's avatar
ahoms committed
413
414
415
416
}

void Camera::getChanSize(Size& chan_size)
{
417
	DEB_MEMBER_FUNCT();
ahoms's avatar
ahoms committed
418
419
420
421
	getCcdSize(chan_size);
	Point nb_chan;
	getNbChan(nb_chan);
	chan_size /= nb_chan;
422
	DEB_RETURN() << DEB_VAR1(chan_size);
ahoms's avatar
ahoms committed
423
424
425
426
427
}

void Camera::xformChanCoords(const Point& point, Point& chan_point, 
			     Corner& ref_corner)
{
428
429
430
	DEB_MEMBER_FUNCT();
	DEB_PARAM() << DEB_VAR1(point);

ahoms's avatar
ahoms committed
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
	Size chan_size;
	getChanSize(chan_size);

	bool good_xchan = isChanActive(Chan1) || isChanActive(Chan3);
	bool good_ychan = isChanActive(Chan1) || isChanActive(Chan2);
	Point flip;
	getFlip(flip);
	XBorder ref_xb = (bool(flip.x) == !good_xchan) ? Left : Right;
	YBorder ref_yb = (bool(flip.y) == !good_ychan) ? Top  : Bottom;

	Point mirror;
	getMirror(mirror);
	if (mirror.x)
		ref_xb = (point.x < chan_size.getWidth())  ? Left : Right;
	if (mirror.y)
		ref_yb = (point.y < chan_size.getHeight()) ? Top  : Bottom;

	ref_corner.set(ref_xb, ref_yb);

	Size ccd_size;
	getCcdSize(ccd_size);

	chan_point = ccd_size.getCornerCoords(point, ref_corner);
454
	DEB_RETURN() << DEB_VAR2(chan_point, ref_corner);
ahoms's avatar
ahoms committed
455
456
457
458
}

void Camera::getImageRoi(const Roi& chan_roi, Roi& image_roi)
{
459
460
461
	DEB_MEMBER_FUNCT();
	DEB_PARAM() << DEB_VAR1(chan_roi);

ahoms's avatar
ahoms committed
462
463
464
465
466
467
468
469
470
471
	Point img_tl, chan_tl = chan_roi.getTopLeft();
	Point img_br, chan_br = chan_roi.getBottomRight();
	Corner c_tl, c_br;
	xformChanCoords(chan_tl, img_tl, c_tl);
	xformChanCoords(chan_br, img_br, c_br);

	Roi unbinned_roi(img_tl, img_br);
	Bin bin;
	getBin(bin);
	image_roi = unbinned_roi.getBinned(bin);
472
473

	DEB_RETURN() << DEB_VAR1(image_roi);
ahoms's avatar
ahoms committed
474
475
476
477
478
}

void Camera::getFinalRoi(const Roi& image_roi, const Point& roi_offset,
			 Roi& final_roi)
{
479
480
481
	DEB_MEMBER_FUNCT();
	DEB_PARAM() << DEB_VAR2(image_roi, roi_offset);

ahoms's avatar
ahoms committed
482
483
484
485
486
	Point tl = image_roi.getTopLeft() + roi_offset;
	Point nb_chan;
	getNbChan(nb_chan);
	Size size = image_roi.getSize() * nb_chan;
	final_roi = Roi(tl, size);
487
488

	DEB_RETURN() << DEB_VAR1(final_roi);
ahoms's avatar
ahoms committed
489
490
491
492
}

void Camera::getChanRoi(const Roi& image_roi, Roi& chan_roi)
{
493
494
495
	DEB_MEMBER_FUNCT();
	DEB_PARAM() << DEB_VAR1(image_roi);

ahoms's avatar
ahoms committed
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
	Bin bin;
	getBin(bin);
	Roi unbinned_roi = image_roi.getUnbinned(bin);
	Point chan_tl, img_tl = unbinned_roi.getTopLeft();
	Point chan_br, img_br = unbinned_roi.getBottomRight();
	Corner c_tl, c_br;
	xformChanCoords(img_tl, chan_tl, c_tl);
	xformChanCoords(img_br, chan_br, c_br);

	chan_roi.setCorners(chan_tl, chan_br);
	chan_tl = chan_roi.getTopLeft();
	chan_br = chan_roi.getBottomRight();

	bool two_xchan = (c_tl.getX() != c_br.getX());
	bool two_ychan = (c_tl.getY() != c_br.getY());
511
512
	DEB_TRACE() << DEB_VAR2(two_xchan, two_ychan);

ahoms's avatar
ahoms committed
513
514
515
516
517
518
519
520
	Size chan_size;
	getChanSize(chan_size);
	if (two_xchan)
		chan_br.x = chan_size.getWidth() - 1;
	if (two_ychan)
		chan_br.y = chan_size.getHeight() - 1;

	chan_roi.setCorners(chan_tl, chan_br);
521
	DEB_RETURN() << DEB_VAR1(chan_roi);
ahoms's avatar
ahoms committed
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
}

void Camera::getImageRoiOffset(const Roi& req_roi, const Roi& image_roi,
			       Point& roi_offset)
{
	Point virt_tl = image_roi.getTopLeft();

	Size ccd_size, image_size;
	getCcdSize(ccd_size);
	image_size = image_roi.getSize();
	Point image_br = image_roi.getBottomRight() + 1;

	Point mirror_tl = ccd_size - image_br - image_size;
	Point req_tl = req_roi.getTopLeft();
	if (req_tl.x >= image_br.x)
		virt_tl.x = mirror_tl.x;
	if (req_tl.y >= image_br.y)
		virt_tl.y = mirror_tl.y;

	roi_offset = virt_tl - image_roi.getTopLeft();
}

void Camera::checkRoiMode(const Roi& roi)
{
	RoiMode roi_mode;
	getRoiMode(roi_mode);
	if (!roi.isActive())
		roi_mode = None;
	else if (roi_mode == None)
		roi_mode = Slow;
	setRoiMode(roi_mode);
}

555
void Camera::checkRoi(const Roi& set_roi, Roi& hw_roi)
ahoms's avatar
ahoms committed
556
{
557
558
	if (!set_roi.isActive()) {
		hw_roi = set_roi;
ahoms's avatar
ahoms committed
559
		return;
560
	}
ahoms's avatar
ahoms committed
561
562
563

	Roi chan_roi;
	Point roi_offset;
564
	processSetRoi(set_roi, hw_roi, chan_roi, roi_offset);
ahoms's avatar
ahoms committed
565
566
}

567
568
void Camera::processSetRoi(const Roi& set_roi, Roi& hw_roi, 
			   Roi& chan_roi, Point& roi_offset)
ahoms's avatar
ahoms committed
569
{
570
571
572
	Roi aligned_roi = set_roi;
	aligned_roi.alignCornersTo(Point(32, 1), Ceil);
	getChanRoi(aligned_roi, chan_roi);
ahoms's avatar
ahoms committed
573
574
	Roi image_roi;
	getImageRoi(chan_roi, image_roi);
575
576
	getImageRoiOffset(set_roi, image_roi, roi_offset);
	getFinalRoi(image_roi, roi_offset, hw_roi);
ahoms's avatar
ahoms committed
577
578
}

579
void Camera::setRoi(const Roi& set_roi)
ahoms's avatar
ahoms committed
580
{
581
582
	checkRoiMode(set_roi);
	if (!set_roi.isActive())
ahoms's avatar
ahoms committed
583
584
		return;

585
	Roi hw_roi, chan_roi;
ahoms's avatar
ahoms committed
586
	Point roi_offset;
587
	processSetRoi(set_roi, hw_roi, chan_roi, roi_offset);
ahoms's avatar
ahoms committed
588
589
590
591
592
593
594
595
596
597
598
599

	Point tl  = chan_roi.getTopLeft();
	Size size = chan_roi.getSize();

	writeRegister(RoiPixelBegin, tl.x);
	writeRegister(RoiPixelWidth, size.getWidth());
	writeRegister(RoiLineBegin,  tl.y);
	writeRegister(RoiLineWidth,  size.getHeight());

	m_roi_offset = roi_offset;
}

600
void Camera::getRoi(Roi& hw_roi)
ahoms's avatar
ahoms committed
601
{
602
603
604
605
606
607
608
	hw_roi.reset();

	RoiMode roi_mode;
	getRoiMode(roi_mode);
	if (roi_mode == None)
		return;

ahoms's avatar
ahoms committed
609
610
611
612
613
614
615
616
617
	int rpb, rpw, rlb, rlw;
	readRegister(RoiPixelBegin, rpb);
	readRegister(RoiPixelWidth, rpw);
	readRegister(RoiLineBegin,  rlb);
	readRegister(RoiLineWidth,  rlw);

	Roi chan_roi(Point(rpb, rlb), Size(rpw, rlw));
	Roi image_roi;
	getImageRoi(chan_roi, image_roi);
618
619
620
	getFinalRoi(image_roi, m_roi_offset, hw_roi);
}

621
void Camera::setTrigMode(TrigMode trig_mode)
622
623
{
	m_trig_mode = trig_mode;
624
	setNbFrames(m_nb_frames);
625
626
}

627
void Camera::getTrigMode(TrigMode& trig_mode)
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
{
	trig_mode = m_trig_mode;
}

void Camera::setTimeUnitFactor(TimeUnitFactor time_unit_factor)
{
	int time_unit = int(time_unit_factor);
	writeRegister(TimeUnit, time_unit);
}

void Camera::getTimeUnitFactor(TimeUnitFactor& time_unit_factor)
{
	int time_unit;
	readRegister(TimeUnit, time_unit);
	time_unit_factor = TimeUnitFactor(time_unit);
}

void Camera::setExpTime(double exp_time)
{
	bool ok = false;
	int exp_val;
	TimeUnitFactor seq_clist[] = { Microseconds, Milliseconds };
	TimeUnitFactor *it, *end = C_LIST_END(seq_clist);
	for (it = seq_clist; it != end; ++it) {
		double factor = TimeUnitFactorMap[*it];
		exp_val = int(exp_time / factor + 0.1);
654
		ok = (exp_val <= MaxRegVal);
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
		if (ok)
			break;
	}
	if (!ok)
		throw LIMA_HW_EXC(InvalidValue, "Exposure time too high");

	TimeUnitFactor time_unit_factor = (exp_val == 0) ? Milliseconds : *it;
	setTimeUnitFactor(time_unit_factor);
	writeRegister(ExpTime, exp_val);
}

void Camera::getExpTime(double& exp_time)
{
	TimeUnitFactor time_unit_factor;
	getTimeUnitFactor(time_unit_factor);
	int exp_val;
	readRegister(ExpTime, exp_val);
	exp_time = exp_val * TimeUnitFactorMap[time_unit_factor];
}

void Camera::setLatTime(double lat_time)
{
	int lat_val = int(lat_time / TimeUnitFactorMap[Milliseconds] + 0.1);
	writeRegister(LatencyTime, lat_val);
}

void Camera::getLatTime(double& lat_time)
{
	int lat_val;
	readRegister(LatencyTime, lat_val);
	lat_time = lat_val * TimeUnitFactorMap[Milliseconds];
}

void Camera::setNbFrames(int nb_frames)
{
	TrigMode trig_mode;
691
	getTrigMode(trig_mode);
692
693
694
695
696
697
698
699
700
701
	int cam_nb_frames = (trig_mode == ExtTrigMult) ? 1 : nb_frames;
	writeRegister(NbFrames, cam_nb_frames);
	m_nb_frames = nb_frames;
}

void Camera::getNbFrames(int& nb_frames)
{
	nb_frames = m_nb_frames;
}

702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
void Camera::getStatus(Status& status)
{
	Espia::Dev& dev = getEspiaDev();
	int ccd_status;
	dev.getCcdStatus(ccd_status);
	status = Status(ccd_status);
}

bool Camera::waitStatus(Status& status, double timeout)
{
	Timestamp end;
	if (timeout > 0)
		end = Timestamp::now() + Timestamp(timeout);

	bool good_status = false;
	Status curr_status;
	while (!good_status && !end.isSet() || (Timestamp::now() < end)) {
		getStatus(curr_status);
		good_status = ((curr_status & status) == status);
	}

	status = curr_status;
	return good_status;
}

727
728
729
void Camera::start()
{
	TrigMode trig_mode;
730
	getTrigMode(trig_mode);
731
732
733
734
735
736
737
	if (trig_mode == IntTrig)
		sendCmd(Start);
}

void Camera::stop()
{
	TrigMode trig_mode;
738
	getTrigMode(trig_mode);
739
740
	if (trig_mode != ExtGate)
		sendCmd(Stop);
741
742
743
744
745
746
747
748

	Status status = Wait;
	waitStatus(status);

	FrameTransferMode ftm;
	getFrameTransferMode(ftm);
	if (ftm == FTM)
		Sleep(MaxReadoutTime);
ahoms's avatar
ahoms committed
749
750
}