firmware  v0.1.2
Chromation Spectrometer Dev-Kit
test_AutoExpose.c
1 #include "unity.h"
2 #include "Mock.h"
3 #include "test_AutoExpose.h"
4 #include "AutoExpose.h"
5 #include "VisCmd.h" // AutoExpose() defined here
6 
7 /* =====[ Test Helpers ]===== */
8 static void _AssertCall(uint16_t num, char const * name)
9 {
11  // Put num and name in the message displayed if test fails
12  GString *message = g_string_new(NULL);
13  g_string_append_printf(message, "`%s` is not call %d", name, num);
14  // Perform the test
15  TEST_ASSERT_TRUE_MESSAGE(
16  AssertCall(mock, num, name),
17  message->str
18  );
19  // Free memory used by GString
20  g_string_free(message, true);
21 }
22 
23 /* =====[ AutoExpose ]===== */
24 void AutoExpose_turns_led1_red_to_indicate_starting(void)
25 {
26  /* =====[ Operate ]===== */
27  AutoExpose();
28 
29  /* =====[ Test ]===== */
30  TEST_PASS();
31 }
32 void AutoExpose_sets_min_peak_at_target_minus_tolerance(void)
33 {
34  /* =====[ Setup ]===== */
35  target = 46420;
36  target_tolerance = 3277;
37  /* =====[ Operate ]===== */
38  uint16_t min_peak = _MinPeak(target, target_tolerance);
39  /* =====[ Test ]===== */
40  TEST_ASSERT_EQUAL_UINT16(target-target_tolerance, min_peak);
41 }
42 void AutoExpose_clamps_min_peak_at_max_dark_if_target_minus_tolerance_is_GREATER_THAN_target(void)
43 {
44  /* =====[ Setup ]===== */
45  max_dark = 4500;
46  target = 46420;
47  target_tolerance = 46421;
48  // greater than test of (a,b) tests for b>a
49  TEST_ASSERT_GREATER_THAN_UINT16(1,2); // example
50  TEST_ASSERT_GREATER_THAN_UINT16(target,target-target_tolerance);
51  /* =====[ Operate ]===== */
52  uint16_t min_peak = _MinPeak(target, target_tolerance);
53  /* =====[ Test ]===== */
54  TEST_ASSERT_EQUAL_UINT16(max_dark, min_peak);
55 }
56 void AutoExpose_clamps_min_peak_at_max_dark_if_target_minus_tolerance_is_LESS_THAN_max_dark(void)
57 {
58  /* =====[ Setup ]===== */
59  max_dark = 4500;
60  target = 46420;
61  target_tolerance = 46400;
62  // less than test of (a,b) tests for b<a
63  TEST_ASSERT_LESS_THAN_UINT16(2,1); // example
64  TEST_ASSERT_LESS_THAN_UINT16(max_dark,target-target_tolerance);
65  /* =====[ Operate ]===== */
66  uint16_t min_peak = _MinPeak(target, target_tolerance);
67  /* =====[ Test ]===== */
68  TEST_ASSERT_EQUAL_UINT16(max_dark, min_peak);
69 }
70 void AutoExpose_sets_max_peak_at_target_plus_tolerance(void)
71 {
72  /* =====[ Setup ]===== */
73  target = 46420;
74  target_tolerance = 3277;
75  /* =====[ Operate ]===== */
76  uint16_t max_peak = _MaxPeak(target, target_tolerance);
77  /* =====[ Test ]===== */
78  TEST_ASSERT_EQUAL_UINT16(target+target_tolerance, max_peak);
79 }
80 void AutoExpose_clamps_max_peak_at_65535_counts_if_target_plus_tolerance_is_LESS_THAN_target(void)
81 {
82  /* =====[ Setup ]===== */
83  target = 46420;
84  target_tolerance = 20000;
85  TEST_ASSERT_LESS_THAN_UINT16(2,1); // example
86  TEST_ASSERT_LESS_THAN_UINT16(
87  target,
89  );
90  /* =====[ Operate ]===== */
91  uint16_t max_peak = _MaxPeak(target, target_tolerance);
92  /* =====[ Test ]===== */
93  TEST_ASSERT_EQUAL_UINT16(UINT16_MAX, max_peak);
94 }
95 void AutoExpose_loops_until_done(void)
96 {
97  TEST_PASS();
98 }
99 void AutoExpose_exposes_the_pixels(void)
100 {
101  /* =====[ Operate ]===== */
102  AutoExpose();
103  /* =====[ Test ]===== */
104 #ifdef LIS
105  _AssertCall(1, "LisExpose");
106 #endif
107 #ifdef S13131
108  _AssertCall(1, "S13131Expose");
109 #endif
110 }
111 void AutoExpose_reads_pixel_counts_into_global_frame_buffer(void)
112 {
113  /* =====[ Operate ]===== */
114  AutoExpose();
115  /* =====[ Test ]===== */
116 #ifdef LIS
117  _AssertCall(2, "LisReadout");
118 #endif
119 #ifdef S13131
120  _AssertCall(2, "S13131Readout");
121 #endif
122 }
123 
124 void AutoExpose_finds_frame_peak_in_range_start_pixel_to_stop_pixel(void)
125 {
126  /* =====[ Setup ]===== */
127  // mock a frame with a peak
128  // TODO(sustainablelab): Why /2? Should be *2.
129  for (uint16_t byte_index; byte_index++ < MAX_NUM_PIXELS/2;)
130  {
131  frame[byte_index] = 0;
132  }
133  // stick peak counts value 0xABCD at pixel 100
134  uint16_t const pixnum = 100;
135  uint16_t byte_index = (pixnum-1)*2;
136  frame[byte_index++] = 0xAB;
137  frame[byte_index] = 0xCD;
138  uint16_t start_pixel = 10;
139  uint16_t stop_pixel = 200;
140  TEST_ASSERT_LESS_THAN_UINT16(2,1); // example
141  TEST_ASSERT_LESS_THAN_UINT16(pixnum,start_pixel); // example
142  TEST_ASSERT_GREATER_THAN_UINT16(1,2); // example
143  TEST_ASSERT_GREATER_THAN_UINT16(pixnum,stop_pixel); // example
144  /* =====[ Operate ]===== */
145  uint16_t peak = GetPeak(start_pixel, stop_pixel);
146  /* =====[ Test ]===== */
147  TEST_ASSERT_EQUAL_UINT16(0xABCD, peak);
148 }
149 void AutoExpose_is_done_if_peak_less_than_max_dark_AND_exposure_at_max(void)
150 {
151  /* =====[ Setup ]===== */
152  // Expect algorithm to stop after first iteration.
153  // Set max_tries above expected number of iterations.
154  max_tries = 2;
155  // Set target well above max_dark
156  target = 46420; target_tolerance = 3277;
157  // Set typical max_dark
158  max_dark = 0x1194; // 4500 in hexadecimal
159  TEST_ASSERT_EQUAL_UINT16(max_dark,4500);
160  // fake frame of data with peak less than max_dark
161  // TODO(sustainablelab): Why /2? Should be *2.
162  for (uint16_t byte_index; byte_index++ < MAX_NUM_PIXELS/2;)
163  {
164  frame[byte_index] = 0;
165  }
166  // stick peak counts value 0x1193 at pixel 100
167  uint16_t const pixnum = 100;
168  uint16_t byte_index = (pixnum-1)*2;
169  frame[byte_index++] = 0x11;
170  frame[byte_index] = 0x93;
171  // autoexpose pixel range includes pixel with 0x1193 counts
172  start_pixel = 10; stop_pixel = 200;
173  /* =====[ Operate ]===== */
174  min_exposure = 5;
175  max_exposure = UINT16_MAX;
176  // Put exposure at max
177  /* ------------------------------- */
178  /* | THIS IS WHAT'S BEING TESTED | */
179  /* ------------------------------- */
180  exposure_ticks = UINT16_MAX;
181  AutoExpose();
182  /* =====[ Test ]===== */
183  // two calls are faked, so divide NumberOfActualCalls by 2
184  uint8_t iterations = NumberOfActualCalls(mock)/2;
185  // expect algorithm to finsh on first try
186  TEST_ASSERT_EQUAL_UINT8(1, iterations);
187 }
188 void AutoExpose_scales_exposure_by_10_if_peak_less_than_max_dark(void)
189 {
190  /* =====[ Setup ]===== */
191  // Set target well above max_dark
192  target = 46420; target_tolerance = 3277;
193  // Set typical max_dark
194  max_dark = 0x1194; // 4500 in hexadecimal
195  TEST_ASSERT_EQUAL_UINT16(max_dark,4500);
196  // fake frame of data with peak less than max_dark
197  // TODO(sustainablelab): Why /2? Should be *2.
198  for (uint16_t byte_index; byte_index++ < MAX_NUM_PIXELS/2;)
199  {
200  frame[byte_index] = 0;
201  }
202  // stick peak counts value 0x1193 at pixel 100
203  uint16_t const pixnum = 100;
204  uint16_t byte_index = (pixnum-1)*2;
205  frame[byte_index++] = 0x11;
206  frame[byte_index] = 0x93;
207  // autoexpose pixel range includes pixel with 0x1193 counts
208  start_pixel = 10; stop_pixel = 200;
209  /* =====[ Operate ]===== */
210  // Put exposure below 65535/10
211  /* ------------------------------- */
212  /* | THIS IS WHAT'S BEING TESTED | */
213  /* ------------------------------- */
214  min_exposure = 5;
215  max_exposure = UINT16_MAX;
216  uint16_t initial_exposure = 50;
217  exposure_ticks = initial_exposure;
218  // ---------------------------------------------------------
219  // | This must run only one iteration to inspect exposure. |
220  // ---------------------------------------------------------
221  max_tries = 1;
222  AutoExpose();
223  /* =====[ Test ]===== */
224  // two calls are faked, so divide NumberOfActualCalls by 2
225  uint8_t iterations = NumberOfActualCalls(mock)/2;
226  // make sure only one iteration was performed
227  TEST_ASSERT_EQUAL_UINT8(1, iterations);
228  // The test: expect exposure is multiplied by 10
229  TEST_ASSERT_EQUAL_UINT16(initial_exposure*10, exposure_ticks);
230 }
231 void AutoExpose_clamps_exposure_at_max_exposure_if_10_x_exposure_is_GREATER_THAN_max_exposure(void)
232 {
233  /* =====[ Setup ]===== */
234  // Set target well above max_dark
235  target = 46420; target_tolerance = 3277;
236  // Set typical max_dark
237  max_dark = 0x1194; // 4500 in hexadecimal
238  TEST_ASSERT_EQUAL_UINT16(max_dark,4500);
239  // fake frame of data with peak less than max_dark
240  // TODO(sustainablelab): Why /2? Should be *2.
241  for (uint16_t byte_index; byte_index++ < MAX_NUM_PIXELS/2;)
242  {
243  frame[byte_index] = 0;
244  }
245  // stick peak counts value 0x1193 at pixel 100
246  uint16_t const pixnum = 100;
247  uint16_t byte_index = (pixnum-1)*2;
248  frame[byte_index++] = 0x11;
249  frame[byte_index] = 0x93;
250  // autoexpose pixel range includes pixel with 0x1193 counts
251  start_pixel = 10; stop_pixel = 200;
252  /* =====[ Operate ]===== */
253  min_exposure = 5;
254  max_exposure = UINT16_MAX;
255  // Put exposure above 65535/10
256  /* ------------------------------- */
257  /* | THIS IS WHAT'S BEING TESTED | */
258  /* ------------------------------- */
259  uint16_t initial_exposure = 10000;
260  exposure_ticks = initial_exposure;
261  // ---------------------------------------------------------
262  // | This must run only one iteration to inspect exposure. |
263  // ---------------------------------------------------------
264  max_tries = 1;
265  AutoExpose();
266  /* =====[ Test ]===== */
267  // two calls are faked, so divide NumberOfActualCalls by 2
268  uint8_t iterations = NumberOfActualCalls(mock)/2;
269  // make sure only one iteration was performed
270  TEST_ASSERT_EQUAL_UINT8(1, iterations);
271  // The test: expect exposure clamps at 65535
272  TEST_ASSERT_EQUAL_UINT16(UINT16_MAX, exposure_ticks);
273 }
274 void AutoExpose_scales_exposure_by_half_if_peak_ABOVE_max_peak(void)
275 {
276  /* =====[ Setup ]===== */
277  // Set target well above max_dark
278  target = 46420; target_tolerance = 3277;
279  uint16_t max_peak = target+target_tolerance;
280  uint16_t peak = 0xC222;
281  TEST_ASSERT_GREATER_THAN_UINT16(1,2); // example
282  TEST_ASSERT_GREATER_THAN_UINT16(max_peak,peak);
283  // Set typical max_dark
284  max_dark = 4500;
285  // fake frame of data with peak ABOVE max_peak
286  // TODO(sustainablelab): Why /2? Should be *2.
287  for (uint16_t byte_index; byte_index++ < MAX_NUM_PIXELS/2;)
288  {
289  frame[byte_index] = 0;
290  }
291  // stick peak counts value 0xC222 at pixel 100
292  uint16_t const pixnum = 100;
293  uint16_t byte_index = (pixnum-1)*2;
294  frame[byte_index++] = 0xC2;
295  frame[byte_index] = 0x22;
296  // autoexpose pixel range includes peak pixel
297  start_pixel = 10; stop_pixel = 200;
298  /* =====[ Operate ]===== */
299  min_exposure = 5;
300  max_exposure = UINT16_MAX;
301  // Put exposure above 11 (so that half exposure > 5)
302  /* ------------------------------- */
303  /* | THIS IS WHAT'S BEING TESTED | */
304  /* ------------------------------- */
305  uint16_t initial_exposure = 500; // PASS for: 10:65535
306  exposure_ticks = initial_exposure;
307  // ---------------------------------------------------------
308  // | This must run only one iteration to inspect exposure. |
309  // ---------------------------------------------------------
310  max_tries = 1;
311  AutoExpose();
312  /* =====[ Test ]===== */
313  // two calls are faked, so divide NumberOfActualCalls by 2
314  uint8_t iterations = NumberOfActualCalls(mock)/2;
315  // make sure only one iteration was performed
316  TEST_ASSERT_EQUAL_UINT8(1, iterations);
317  // The test: expect exposure is scaled by half
318  TEST_ASSERT_EQUAL_UINT16(initial_exposure/2, exposure_ticks);
319  // >>1 is the same as dividing by 2
320  TEST_ASSERT_EQUAL_UINT16(initial_exposure>>1, exposure_ticks);
321 }
322 void AutoExpose_clamps_exposure_at_min_exposure_if_half_exposure_is_LESS_THAN_min_exposure(void)
323 {
324  /* =====[ Setup ]===== */
325  // Set target well above max_dark
326  target = 46420; target_tolerance = 3277;
327  uint16_t max_peak = target+target_tolerance;
328  uint16_t peak = 0xC222;
329  TEST_ASSERT_GREATER_THAN_UINT16(1,2); // example
330  TEST_ASSERT_GREATER_THAN_UINT16(max_peak,peak);
331  // Set typical max_dark
332  max_dark = 4500;
333  // fake frame of data with peak
334  // TODO(sustainablelab): Why /2? Should be *2.
335  for (uint16_t byte_index; byte_index++ < MAX_NUM_PIXELS/2;)
336  {
337  frame[byte_index] = 0;
338  }
339  // stick peak counts value 0xC222 at pixel 100
340  uint16_t const pixnum = 100;
341  uint16_t byte_index = (pixnum-1)*2;
342  frame[byte_index++] = 0xC2;
343  frame[byte_index] = 0x22;
344  // autoexpose pixel range includes peak pixel
345  start_pixel = 10; stop_pixel = 200;
346  /* =====[ Operate ]===== */
347  max_exposure = UINT16_MAX;
348  /* ------------------------------- */
349  /* | THIS IS WHAT'S BEING TESTED | */
350  /* ------------------------------- */
351  min_exposure = 5;
352  // Put exposure below 10 (so that half exposure < 5)
353  exposure_ticks = 9;
354  // ---------------------------------------------------------
355  // | This must run only one iteration to inspect exposure. |
356  // ---------------------------------------------------------
357  max_tries = 1;
358  AutoExpose();
359  /* =====[ Test ]===== */
360  // two calls are faked, so divide NumberOfActualCalls by 2
361  uint8_t iterations = NumberOfActualCalls(mock)/2;
362  // make sure only one iteration was performed
363  TEST_ASSERT_EQUAL_UINT8(1, iterations);
364  // The test: expect exposure clamps at min_exposure
365  TEST_ASSERT_EQUAL_UINT16(min_exposure, exposure_ticks);
366 }
367 void AutoExpose_is_done_if_peak_BELOW_min_peak_and_exposure_at_max_exposure(void)
368 {
369  /* =====[ Setup ]===== */
370  // Expect algorithm to stop after first iteration.
371  // Set max_tries above expected number of iterations.
372  max_tries = 2;
373  // Set target below min_peak
374  target = 46420; target_tolerance = 3277;
375  uint16_t min_peak = target - target_tolerance;
376  uint16_t peak = 0xA886;
377  TEST_ASSERT_LESS_THAN_UINT16(2,1); // example
378  TEST_ASSERT_LESS_THAN_UINT16(min_peak,peak); // example
379 
380  // Set typical max_dark
381  max_dark = 0x1194; // 4500 in hexadecimal
382  TEST_ASSERT_EQUAL_UINT16(max_dark,4500);
383  // fake frame of data with peak
384  // TODO(sustainablelab): Why /2? Should be *2.
385  for (uint16_t byte_index; byte_index++ < MAX_NUM_PIXELS/2;)
386  {
387  frame[byte_index] = 0;
388  }
389  // stick peak counts value 0xA886 at pixel 100
390  uint16_t const pixnum = 100;
391  uint16_t byte_index = (pixnum-1)*2;
392  frame[byte_index++] = 0xA8;
393  frame[byte_index] = 0x86;
394  // autoexpose pixel range includes peak pixel
395  start_pixel = 10; stop_pixel = 200;
396  /* =====[ Operate ]===== */
397  min_exposure = 5;
398  max_exposure = UINT16_MAX;
399  // Put exposure at max
400  /* ------------------------------- */
401  /* | THIS IS WHAT'S BEING TESTED | */
402  /* ------------------------------- */
403  exposure_ticks = UINT16_MAX;
404  AutoExpose();
405  /* =====[ Test ]===== */
406  // two calls are faked, so divide NumberOfActualCalls by 2
407  uint8_t iterations = NumberOfActualCalls(mock)/2;
408  // expect algorithm to finsh on first try
409  TEST_ASSERT_EQUAL_UINT8(1, iterations);
410 }
411 void AutoExpose_scales_exposure_by_target_div_peak_if_peak_BELOW_min_peak_and_exposure_not_at_max(void)
412 {
413  /* =====[ Setup ]===== */
414  target = 46420; target_tolerance = 3277;
415  uint16_t min_peak = target - target_tolerance;
416  // Set peak below min_peak
417  uint16_t peak = 0xA886;
418  TEST_ASSERT_LESS_THAN_UINT16(2,1); // example
419  TEST_ASSERT_LESS_THAN_UINT16(min_peak,peak); // example
420 
421  // Set typical max_dark
422  max_dark = 0x1194; // 4500 in hexadecimal
423  TEST_ASSERT_EQUAL_UINT16(max_dark,4500);
424  // fake frame of data with peak
425  // TODO(sustainablelab): Why /2? Should be *2.
426  for (uint16_t byte_index; byte_index++ < MAX_NUM_PIXELS/2;)
427  {
428  frame[byte_index] = 0;
429  }
430  // stick peak counts value 0xA886 at pixel 100
431  uint16_t const pixnum = 100;
432  uint16_t byte_index = (pixnum-1)*2;
433  frame[byte_index++] = 0xA8;
434  frame[byte_index] = 0x86;
435  // autoexpose pixel range includes peak pixel
436  start_pixel = 10; stop_pixel = 200;
437  /* =====[ Operate ]===== */
438  min_exposure = 5;
439  max_exposure = UINT16_MAX;
440  // Put exposure below max
441  /* ------------------------------- */
442  /* | THIS IS WHAT'S BEING TESTED | */
443  /* ------------------------------- */
444  uint16_t initial_exposure = 50;
445  exposure_ticks = initial_exposure;
446  // ---------------------------------------------------------
447  // | This must run only one iteration to inspect exposure. |
448  // ---------------------------------------------------------
449  max_tries = 1;
450  AutoExpose();
451  /* =====[ Test ]===== */
452  // two calls are faked, so divide NumberOfActualCalls by 2
453  uint8_t iterations = NumberOfActualCalls(mock)/2;
454  // make sure only one iteration was performed
455  TEST_ASSERT_EQUAL_UINT8(1, iterations);
456 
457  // The test: expect exposure scales by target/peak
458 
459  /* ---------------------------------------------------- */
460  /* | NOTE ON UNSIGNED INTEGER ARITHMETIC | */
461  /* | (target/peak)*exposure != (target*exposure)/peak | */
462  /* | example: using test values, lhs == 50, rhs == 53 | */
463  /* ---------------------------------------------------- */
464 
465  TEST_ASSERT_NOT_EQUAL((target/peak)*initial_exposure, exposure_ticks);
466  TEST_ASSERT_EQUAL_UINT16((target*initial_exposure)/peak, exposure_ticks);
467 }
468 void AutoExpose_clamps_exposure_at_max_exposure_if_gain_is_GREATER_THAN_max_exposure(void)
469 {
470  /* =====[ Setup ]===== */
471  target = 46420; target_tolerance = 3277;
472 
473  // Set typical max_dark
474  max_dark = 0x1194; // 4500 in hexadecimal
475  TEST_ASSERT_EQUAL_UINT16(max_dark,4500);
476 
477  // ---------------------------------------------
478  // | Biggest gain happens when peak = max_dark |
479  // | Using test values, gain = 10.3 |
480  // ---------------------------------------------
481 
482  // fake frame of data with peak at max_dark
483  // TODO(sustainablelab): Why /2? Should be *2.
484  for (uint16_t byte_index; byte_index++ < MAX_NUM_PIXELS/2;)
485  {
486  frame[byte_index] = 0;
487  }
488  // stick peak counts value 0x1194 at pixel 100
489  uint16_t const pixnum = 100;
490  uint16_t byte_index = (pixnum-1)*2;
491  frame[byte_index++] = 0x11;
492  frame[byte_index] = 0x94;
493  // autoexpose pixel range includes peak pixel
494  start_pixel = 10; stop_pixel = 200;
495  /* =====[ Operate ]===== */
496  min_exposure = 5;
497  max_exposure = UINT16_MAX;
498  // Put exposure below max
499  /* ------------------------------- */
500  /* | THIS IS WHAT'S BEING TESTED | */
501  /* ------------------------------- */
502  // set exposure above 6353 to test clamping action
503  uint16_t initial_exposure = 6354; // PASS: 6354:65535
504  exposure_ticks = initial_exposure;
505  // ---------------------------------------------------------
506  // | This must run only one iteration to inspect exposure. |
507  // ---------------------------------------------------------
508  max_tries = 1;
509  AutoExpose();
510  /* =====[ Test ]===== */
511  // two calls are faked, so divide NumberOfActualCalls by 2
512  uint8_t iterations = NumberOfActualCalls(mock)/2;
513  // make sure only one iteration was performed
514  TEST_ASSERT_EQUAL_UINT8(1, iterations);
515 
516  // The test: expect exposure clamps at max_exposure
517  TEST_ASSERT_EQUAL_UINT16(UINT16_MAX, exposure_ticks);
518 }
519 void AutoExpose_is_done_if_peak_is_in_the_target_range(void)
520 {
521  /* =====[ Setup ]===== */
522  // Expect algorithm to stop after first iteration.
523  // Set max_tries above expected number of iterations.
524  max_tries = 2;
525 
526  // Use the recommended values
527  target = 46420; target_tolerance = 3277; max_dark = 4500;
528 
529  // put peak in the target range by making peak = target
530  uint16_t peak = 0xB554;
531  TEST_ASSERT_EQUAL_UINT16(target, peak);
532 
533  // fake frame of data with peak in target range
534  // TODO(sustainablelab): Why /2? Should be *2.
535  for (uint16_t byte_index; byte_index++ < MAX_NUM_PIXELS/2;)
536  {
537  frame[byte_index] = 0;
538  }
539  // stick peak counts value 0xB554 at pixel 100
540  uint16_t const pixnum = 100;
541  uint16_t byte_index = (pixnum-1)*2;
542  frame[byte_index++] = 0xB5;
543  frame[byte_index] = 0x54;
544  // autoexpose pixel range includes peak pixel
545  start_pixel = 10; stop_pixel = 200;
546  /* =====[ Operate ]===== */
547  min_exposure = 5;
548  max_exposure = UINT16_MAX;
549  uint16_t initial_exposure = 50;
550  exposure_ticks = initial_exposure;
551  AutoExpose();
552  // make sure AutoExpose did not change exposure
553  TEST_ASSERT_EQUAL_UINT16(initial_exposure, exposure_ticks);
554  /* =====[ Test ]===== */
555  // two calls are faked, so divide NumberOfActualCalls by 2
556  uint8_t iterations = NumberOfActualCalls(mock)/2;
557  // The test: only one iteration is performed
558  TEST_ASSERT_EQUAL_UINT8(1, iterations);
559 }
560 void AutoExpose_turns_led1_green_to_indicate_it_hit_the_target_range(void)
561 {
562  TEST_PASS();
563 }
564 void AutoExpose_gives_up_if_it_iterates_for_max_tries(void)
565 {
566  /* =====[ Setup ]===== */
567  // use typical values
568  target = 46420; target_tolerance = 3277; max_dark = 4500;
569  min_exposure = 5; max_exposure = UINT16_MAX;
570  exposure_ticks = 50;
571 
572  // Set peak one count below min_peak to put it *just* outside
573  // the target range. AutoExpose should initially follow path
574  // to apply calculated gain to exposure. I'm trying to set up
575  // a scenario where it takes a while for the exposure to max
576  // out.
577 
578  uint16_t min_peak = target - target_tolerance;
579  uint16_t peak = 0xA886;
580  TEST_ASSERT_EQUAL_UINT16(min_peak-1, peak);
581 
582  // fake frame of data with peak
583  // TODO(sustainablelab): Why /2? Should be *2.
584  for (uint16_t byte_index; byte_index++ < MAX_NUM_PIXELS/2;)
585  {
586  frame[byte_index] = 0;
587  }
588  // stick peak counts value at pixel 100
589  uint16_t const pixnum = 100;
590  uint16_t byte_index = (pixnum-1)*2;
591  frame[byte_index++] = 0xA8;
592  frame[byte_index] = 0x86;
593  // autoexpose pixel range includes peak pixel
594  start_pixel = 10; stop_pixel = 200;
595 
596  /* =====[ Operate ]===== */
597  // ---------------------------------
598  // | This is the value under test. |
599  // ---------------------------------
600  // 101 tries was the best I could do.
601  // In theory, some combo of values makes 255 possible.
602  // 255 is the maximum number of tries because of the data type.
603  // But 101 is good enough to show the loop working.
604  //
605  // Note that 0 does not work, but SetAutoExposeConfig returns
606  // an ERROR if the user tries to set max_tries to 0.
607  max_tries = 50; // PASS: 1:101
608  AutoExpose();
609 
610  /* =====[ Test ]===== */
611  // -------------------------------------------
612  // | The peak does not change (it is faked). |
613  // | But the exposure DOES change. So the |
614  // | loop does NOT always follows the same |
615  // | path. Expect loop runs for max_tries. |
616  // -------------------------------------------
617 
618  // two calls are faked, so divide NumberOfActualCalls by 2
619  uint8_t iterations = NumberOfActualCalls(mock)/2;
620  TEST_ASSERT_EQUAL_UINT8(max_tries, iterations);
621 }
uint16_t max_exposure
max_exposure is 1.31 seconds (65535 20µs-cycles) This is the 16-bit limit, UINT16_MAX,...
Definition: AutoExpose.c:12
uint16_t start_pixel
AutoExpose() ignores pixels below start_pixel.
Definition: AutoExpose.c:6
uint8_t max_tries
maximum number of tries before AutoExpose() gives up
Definition: AutoExpose.c:5
uint16_t stop_pixel
AutoExpose() ignores pixels above stop_pixel.
Definition: AutoExpose.c:7
uint16_t target_tolerance
target ± target_tolerance is the target peak counts range for AutoExpose().
Definition: AutoExpose.c:9
uint16_t max_dark
max_dark is a conservative estimate on the largest dark offset
Definition: AutoExpose.c:10
uint16_t target
target peak counts for AutoExpose().
Definition: AutoExpose.c:8
uint16_t min_exposure
min_exposure is 100 microseconds (five 20µs-cycles) This is a safe lower limit to avoid dead frames.
Definition: AutoExpose.c:11
uint16_t exposure_ticks
LIS-770i exposure time.
Definition: Lis.c:32
#define MAX_NUM_PIXELS
LIS-770i maximum number of pixels.
Definition: Lis.h:400
uint8_t frame[]
One frame of pixel data is, at most, 1568 bytes.
Definition: VisCmd.c:2
uint16_t GetPeak(uint16_t const, uint16_t const)
Definition: VisCmd.c:29
uint16_t AutoExpose(void)
Definition: VisCmd.c:81