1 /*
2 *
3 * SPDX-License-Identifier: GPL-2.0
4 *
5 * Copyright (C) 2011-2018 ARM or its affiliates
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19
20 #include "acamera_fw.h"
21 #include "acamera_math.h"
22 #include "system_timer.h"
23 #include "acamera_command_api.h"
24 #include "cmos_fsm.h"
25
26 #include "acamera_logger.h"
27
28 #define is_short_exposure_frame( base ) ( ACAMERA_FSM2CTX_PTR( p_fsm )->frame & 1 )
29
30 #ifdef LOG_MODULE
31 #undef LOG_MODULE
32 #define LOG_MODULE LOG_MODULE_CMOS
33 #endif
34
35 #define EXPOSURE_PARTITION_INTEGRATION_TIME_INDEX 0
36 #define EXPOSURE_PARTITION_GAIN_INDEX 1
37
cmos_get_partition_lut(cmos_fsm_ptr_t p_fsm,cmos_partition_lut_index_t lut_idx)38 uint16_t *cmos_get_partition_lut( cmos_fsm_ptr_t p_fsm, cmos_partition_lut_index_t lut_idx )
39 {
40 uint32_t i = 0;
41 uint16_t *p_luts = _GET_USHORT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_EXPOSURE_PARTITION_LUTS );
42 uint32_t lut_len = _GET_COLS( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_EXPOSURE_PARTITION_LUTS );
43 uint32_t lut_count = _GET_ROWS( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_EXPOSURE_PARTITION_LUTS );
44
45 if ( lut_idx >= PARTITION_LUT_INDEX_MAX ) {
46 LOG( LOG_CRIT, "Error: invalid partition lut index: %d, max: %d.", lut_idx, PARTITION_LUT_INDEX_MAX - 1 );
47 return NULL;
48 }
49
50 // each lut has SYSTEM_EXPOSURE_PARTITION_VALUE_COUNT items
51 if ( lut_len != SYSTEM_EXPOSURE_PARTITION_VALUE_COUNT ) {
52 LOG( LOG_CRIT, "Error: corrupted calibration luts, lut_len: %d, expected: %d.", lut_len, SYSTEM_EXPOSURE_PARTITION_VALUE_COUNT );
53 return NULL;
54 }
55
56 if ( lut_idx >= lut_count ) {
57 LOG( LOG_CRIT, "Error: corrupted calibration luts, max_index: %d, expected: %d.", lut_count - 1, lut_idx );
58 return NULL;
59 }
60
61 p_luts += lut_len * lut_idx;
62
63 for ( i = 0; i < lut_len; i += 2 ) {
64 LOG( LOG_DEBUG, "%d - %d", p_luts[i], p_luts[i + 1] );
65 }
66
67 return p_luts;
68 }
69
cmos_update_exposure_partitioning_lut(cmos_fsm_ptr_t p_fsm)70 void cmos_update_exposure_partitioning_lut( cmos_fsm_ptr_t p_fsm )
71 {
72 int i;
73 int32_t param[2] = {0, 0}; // in log2
74
75
76 uint16_t *exposure_partitions = cmos_get_partition_lut( p_fsm, PARTITION_LUT_BALANED_INDEX );
77 #ifdef AE_SPLIT_PRESET_ID
78 if ( p_fsm->strategy == AE_SPLIT_INTEGRATION_PRIORITY ) {
79 exposure_partitions = cmos_get_partition_lut( p_fsm, PARTITION_LUT_INTEGRATION_PRIORITY_INDEX );
80 }
81 #endif
82
83 fsm_param_sensor_info_t sensor_info;
84 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_SENSOR_INFO, NULL, 0, &sensor_info, sizeof( sensor_info ) );
85
86 int32_t max_gain = sensor_info.again_log2_max + sensor_info.dgain_log2_max + p_fsm->maximum_isp_digital_gain;
87 for ( i = 0; i < SYSTEM_EXPOSURE_PARTITION_VALUE_COUNT; ++i ) {
88 // exposure_partitions has {integration_time, gain } pairs,
89 // so if i is even number, such as 0, 2, means int_time, odd num means gain.
90 int i_param = i & 1;
91 int32_t addon = 0;
92 uint16_t v = exposure_partitions[i];
93
94 switch ( i_param ) {
95 case EXPOSURE_PARTITION_INTEGRATION_TIME_INDEX:
96 if ( !v ) {
97 addon = acamera_log2_fixed_to_fixed( sensor_info.integration_time_limit, 0, LOG2_GAIN_SHIFT );
98 } else {
99 int32_t lines = cmos_convert_integration_time_ms2lines( p_fsm, v );
100 if ( lines < sensor_info.integration_time_min ) {
101 lines = sensor_info.integration_time_min;
102 }
103 addon = acamera_log2_fixed_to_fixed( lines, 0, LOG2_GAIN_SHIFT );
104 }
105 break;
106 case EXPOSURE_PARTITION_GAIN_INDEX:
107 if ( !v ) {
108 addon = max_gain;
109 } else {
110 addon = acamera_log2_fixed_to_fixed( v, 0, LOG2_GAIN_SHIFT );
111 }
112 break;
113 }
114 addon -= param[i_param];
115 if ( addon < 0 ) {
116 addon = 0;
117 }
118 p_fsm->exp_lut[i] = addon;
119 param[i_param] += addon;
120 }
121 }
122
_process_fps_cnt(fps_counter_t * fps_cnt)123 void _process_fps_cnt( fps_counter_t *fps_cnt )
124 {
125 uint32_t cur_tick = system_timer_timestamp();
126 uint32_t frame_ticks = cur_tick - fps_cnt->last_tick;
127 fps_cnt->avg_frame_ticks += frame_ticks - ( fps_cnt->avg_frame_ticks >> 4 );
128 fps_cnt->last_tick = cur_tick;
129 }
130
_init_fps_cnt(fps_counter_t * fps_cnt)131 void _init_fps_cnt( fps_counter_t *fps_cnt )
132 {
133 fps_cnt->last_tick = 0;
134 fps_cnt->avg_frame_ticks = ( system_timer_frequency() / 15 ) << 4; // initially it's something like 15 FPS // division by zero is checked
135 system_timer_init();
136 fps_cnt->last_tick = system_timer_timestamp();
137 }
138
cmos_get_fps(cmos_fsm_ptr_t p_fsm)139 uint16_t cmos_get_fps( cmos_fsm_ptr_t p_fsm )
140 {
141 uint64_t tps = system_timer_frequency();
142 uint16_t fps;
143 if ( p_fsm->fps_cnt.avg_frame_ticks ) {
144 uint64_t _tps = ( tps << ( 8 + 4 ) );
145 fps = (uint16_t)div64_u64( _tps, p_fsm->fps_cnt.avg_frame_ticks ); // division by zero is checked
146 } else {
147 LOG( LOG_CRIT, "AVOIDED DIVISION BY ZERO" );
148 fps = 15 << 8;
149 }
150 return fps;
151 }
152
cmos_init(cmos_fsm_ptr_t p_fsm)153 void cmos_init( cmos_fsm_ptr_t p_fsm )
154 {
155 #ifdef AE_SPLIT_PRESET_ID
156 p_fsm->strategy = AE_SPLIT_BALANCED;
157 #endif
158
159 p_fsm->mask.repeat_irq_mask = ACAMERA_IRQ_MASK( ACAMERA_IRQ_FRAME_START ) | ACAMERA_IRQ_MASK( ACAMERA_IRQ_FRAME_END );
160 cmos_request_interrupt( p_fsm, p_fsm->mask.repeat_irq_mask );
161
162 #ifdef FLASH_XENON
163 p_fsm->flash_state = flash_get_init_state();
164 p_fsm->flash_skip_charge = 1;
165 #endif
166 _init_fps_cnt( &p_fsm->fps_cnt );
167
168
169 #if FILTER_LONG_INT_TIME || FILTER_SHORT_INT_TIME
170 uint16_t i;
171 #endif
172 #if FILTER_LONG_INT_TIME
173 for ( i = 0; i < FILTER_LONG_INT_TIME; i++ ) {
174 p_fsm->long_it_hist.v[i] = 1;
175 }
176 p_fsm->long_it_hist.sum = FILTER_LONG_INT_TIME;
177 p_fsm->long_it_hist.p = &( p_fsm->long_it_hist.v[0] );
178 #endif
179
180 #if FILTER_SHORT_INT_TIME
181 for ( i = 0; i < FILTER_SHORT_INT_TIME; i++ ) {
182 p_fsm->short_it_hist.v[i] = 1;
183 }
184 p_fsm->short_it_hist.sum = FILTER_SHORT_INT_TIME;
185 p_fsm->short_it_hist.p = &( p_fsm->short_it_hist.v[0] );
186 #endif
187
188 system_spinlock_init( &p_fsm->exp_lock );
189 }
190
cmos_alloc_integration_time(cmos_fsm_ptr_t p_fsm,int32_t int_time)191 void cmos_alloc_integration_time( cmos_fsm_ptr_t p_fsm, int32_t int_time )
192 {
193 // We should set as maximum as possible analogue gain less than or equals target_gain
194 unsigned int new_integration_time_short;
195 cmos_control_param_t *param = (cmos_control_param_t *)_GET_UINT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_CONTROL );
196
197 fsm_param_sensor_info_t sensor_info;
198 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_SENSOR_INFO, NULL, 0, &sensor_info, sizeof( sensor_info ) );
199
200 uint32_t min_integration_time_short = sensor_info.integration_time_min;
201 uint32_t max_integration_time_short = sensor_info.integration_time_limit;
202 if ( param->global_manual_max_integration_time && max_integration_time_short > param->global_max_integration_time ) {
203 max_integration_time_short = param->global_max_integration_time;
204 }
205 if ( param->global_manual_integration_time ) {
206 new_integration_time_short = param->global_integration_time;
207 } else {
208 new_integration_time_short = acamera_math_exp2( int_time, LOG2_GAIN_SHIFT, 0 );
209 }
210 if ( new_integration_time_short < min_integration_time_short ) {
211 new_integration_time_short = min_integration_time_short;
212 } else if ( new_integration_time_short > max_integration_time_short ) {
213 new_integration_time_short = max_integration_time_short;
214 }
215
216 #if FILTER_SHORT_INT_TIME
217 //rotate the FIFO
218 if ( ++p_fsm->short_it_hist.p > &( p_fsm->short_it_hist.v[FILTER_SHORT_INT_TIME - 1] ) )
219 p_fsm->short_it_hist.p = &( p_fsm->short_it_hist.v[0] );
220 p_fsm->short_it_hist.sum -= *p_fsm->short_it_hist.p;
221 *p_fsm->short_it_hist.p = new_integration_time_short;
222 p_fsm->short_it_hist.sum += *p_fsm->short_it_hist.p;
223
224 new_integration_time_short = p_fsm->short_it_hist.sum / FILTER_SHORT_INT_TIME; // division by zero is checked
225 #endif
226
227 p_fsm->prev_integration_time_short = p_fsm->integration_time_short;
228 p_fsm->integration_time_short = new_integration_time_short;
229 }
230
cmos_alloc_sensor_analog_gain(cmos_fsm_ptr_t p_fsm,int32_t gain)231 int32_t cmos_alloc_sensor_analog_gain( cmos_fsm_ptr_t p_fsm, int32_t gain )
232 {
233 cmos_control_param_t *param = (cmos_control_param_t *)_GET_UINT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_CONTROL );
234
235 if ( gain < 0 ) {
236 return 0;
237 }
238
239 fsm_param_sensor_info_t sensor_info;
240 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_SENSOR_INFO, NULL, 0, &sensor_info, sizeof( sensor_info ) );
241
242 int32_t max_gain = param->global_max_sensor_analog_gain << ( LOG2_GAIN_SHIFT - 5 );
243 if ( gain > max_gain ) {
244 gain = max_gain;
245 }
246
247 acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_SENSOR_ALLOC_ANALOG_GAIN, &gain, sizeof( gain ) );
248
249 // gain will be changed inside function, so we can return gain as the real gain.
250 return gain;
251 }
252
cmos_alloc_sensor_digital_gain(cmos_fsm_ptr_t p_fsm,int32_t gain)253 int32_t cmos_alloc_sensor_digital_gain( cmos_fsm_ptr_t p_fsm, int32_t gain )
254 {
255 cmos_control_param_t *param = (cmos_control_param_t *)_GET_UINT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_CONTROL );
256 if ( gain < 0 ) {
257 return 0;
258 }
259
260 fsm_param_sensor_info_t sensor_info;
261 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_SENSOR_INFO, NULL, 0, &sensor_info, sizeof( sensor_info ) );
262
263 int32_t max_gain = MIN( sensor_info.dgain_log2_max, (int32_t)param->global_max_sensor_digital_gain << ( LOG2_GAIN_SHIFT - 5 ) );
264 if ( gain > max_gain ) {
265 gain = max_gain;
266 }
267
268 acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_SENSOR_ALLOC_DIGITAL_GAIN, &gain, sizeof( gain ) );
269
270 if ( gain < 0 ) {
271 gain = 0; // special mode like native HDR
272 }
273 return gain;
274 }
275
cmos_alloc_isp_digital_gain(cmos_fsm_ptr_t p_fsm,int32_t gain)276 int32_t cmos_alloc_isp_digital_gain( cmos_fsm_ptr_t p_fsm, int32_t gain )
277 {
278 cmos_control_param_t *param = (cmos_control_param_t *)_GET_UINT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_CONTROL );
279 if ( gain < 0 ) {
280 return 0;
281 }
282 if ( gain > p_fsm->maximum_isp_digital_gain ) {
283 gain = p_fsm->maximum_isp_digital_gain;
284 }
285 int32_t max_gain = param->global_max_isp_digital_gain << ( LOG2_GAIN_SHIFT - 5 );
286 if ( gain > max_gain ) {
287 gain = max_gain;
288 }
289 return gain;
290 }
291
cmos_get_manual_again_log2(cmos_fsm_ptr_t p_fsm)292 int32_t cmos_get_manual_again_log2( cmos_fsm_ptr_t p_fsm )
293 {
294 cmos_control_param_t *param = (cmos_control_param_t *)_GET_UINT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_CONTROL );
295 if ( param->global_manual_sensor_analog_gain ) {
296 int32_t gain = param->global_sensor_analog_gain << ( LOG2_GAIN_SHIFT - 5 );
297 return cmos_alloc_sensor_analog_gain( p_fsm, gain );
298 }
299 return -1; // negative means it is not manual
300 }
301
cmos_get_manual_dgain_log2(cmos_fsm_ptr_t p_fsm)302 int32_t cmos_get_manual_dgain_log2( cmos_fsm_ptr_t p_fsm )
303 {
304 cmos_control_param_t *param = (cmos_control_param_t *)_GET_UINT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_CONTROL );
305 if ( param->global_manual_sensor_digital_gain ) {
306 int32_t gain = ( param->global_sensor_digital_gain << ( LOG2_GAIN_SHIFT - 5 ) );
307 return cmos_alloc_sensor_digital_gain( p_fsm, gain );
308 }
309 return -1; // negative means it is not manual
310 }
311
cmos_get_manual_isp_dgain_log2(cmos_fsm_ptr_t p_fsm)312 int32_t cmos_get_manual_isp_dgain_log2( cmos_fsm_ptr_t p_fsm )
313 {
314 cmos_control_param_t *param = (cmos_control_param_t *)_GET_UINT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_CONTROL );
315 if ( param->global_manual_isp_digital_gain ) {
316 int32_t gain = ( param->global_isp_digital_gain << ( LOG2_GAIN_SHIFT - 5 ) );
317 return cmos_alloc_isp_digital_gain( p_fsm, gain );
318 }
319 return -1; // negative means it is not manual
320 }
321
cmos_convert_integration_time_ms2lines(cmos_fsm_ptr_t p_fsm,int time_ms)322 int cmos_convert_integration_time_ms2lines( cmos_fsm_ptr_t p_fsm, int time_ms )
323 {
324 fsm_param_sensor_info_t sensor_info;
325 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_SENSOR_INFO, NULL, 0, &sensor_info, sizeof( sensor_info ) );
326
327 int res = sensor_info.lines_per_second * time_ms / 1000; // division by zero is checked
328 return res;
329 }
330
cmos_get_frame_exposure_set(cmos_fsm_ptr_t p_fsm,int i_frame)331 exposure_set_t *cmos_get_frame_exposure_set( cmos_fsm_ptr_t p_fsm, int i_frame )
332 {
333 int pos = p_fsm->exposure_hist_pos + i_frame;
334 if ( pos < 0 ) {
335 pos += ( sizeof( p_fsm->exposure_hist ) / sizeof( p_fsm->exposure_hist[0] ) ); // division by zero is checked
336 } else if ( pos >= ( sizeof( p_fsm->exposure_hist ) / sizeof( p_fsm->exposure_hist[0] ) ) ) // division by zero is checked
337 {
338 pos -= ( sizeof( p_fsm->exposure_hist ) / sizeof( p_fsm->exposure_hist[0] ) ); // division by zero is checked
339 }
340 return p_fsm->exposure_hist + pos;
341 }
342
cmos_store_frame_exposure_set(cmos_fsm_ptr_t p_fsm,exposure_set_t * p_set)343 static void cmos_store_frame_exposure_set( cmos_fsm_ptr_t p_fsm, exposure_set_t *p_set )
344 {
345 fsm_param_sensor_info_t sensor_info;
346 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_SENSOR_INFO, NULL, 0, &sensor_info, sizeof( sensor_info ) );
347
348 p_set->data.integration_time = p_fsm->integration_time_short;
349
350 p_set->data.isp_dgain_log2 = p_fsm->isp_dgain_log2;
351 int32_t prev_again;
352
353 if ( sensor_info.sensor_exp_number == 4 ) {
354
355 p_set->data.integration_time_long = p_fsm->integration_time_long;
356 p_set->data.integration_time_medium = p_fsm->integration_time_medium;
357 p_set->data.integration_time_medium2 = p_fsm->integration_time_medium2;
358
359 p_set->data.exposure_ratio_short = 64 * (uint32_t)p_fsm->integration_time_medium / p_fsm->integration_time_short;
360 p_set->data.exposure_ratio_medium = 64 * (uint32_t)p_fsm->integration_time_medium2 / p_fsm->integration_time_medium;
361
362 switch ( sensor_info.isp_exposure_channel_delay ) {
363 case 1:
364 prev_again = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->info.again_log2;
365 p_set->data.exposure_ratio_medium2 = 64 * (uint32_t)p_fsm->integration_time_long / p_fsm->integration_time_medium2 * acamera_math_exp2( prev_again - p_fsm->again_val_log2, LOG2_GAIN_SHIFT, 8 ) >> 8;
366 break;
367 default:
368 p_set->data.exposure_ratio_medium2 = 64 * (uint32_t)p_fsm->integration_time_long / p_fsm->integration_time_medium2;
369 break;
370 }
371
372 } else if ( sensor_info.sensor_exp_number == 3 ) {
373 p_set->data.integration_time_medium = p_fsm->integration_time_medium;
374 p_set->data.exposure_ratio_short = 64 * (uint32_t)p_fsm->integration_time_medium / p_fsm->integration_time_short;
375 p_set->data.integration_time_long = p_fsm->integration_time_long;
376
377 switch ( sensor_info.isp_exposure_channel_delay ) {
378 case 1:
379 prev_again = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->info.again_log2;
380 p_set->data.exposure_ratio_medium = 64 * (uint32_t)p_fsm->integration_time_long / p_fsm->integration_time_medium * acamera_math_exp2( prev_again - p_fsm->again_val_log2, LOG2_GAIN_SHIFT, 8 ) >> 8;
381 break;
382 default:
383 p_set->data.exposure_ratio_medium = 64 * (uint32_t)p_fsm->integration_time_long / p_fsm->integration_time_medium;
384 break;
385 }
386
387 } else if ( sensor_info.sensor_exp_number == 2 ) {
388 p_set->data.integration_time_long = p_fsm->integration_time_long;
389
390 switch ( sensor_info.isp_exposure_channel_delay ) {
391 case 1:
392 prev_again = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->info.again_log2;
393 p_set->data.exposure_ratio = 64 * (uint32_t)p_fsm->integration_time_long / p_fsm->integration_time_short * acamera_math_exp2( prev_again - p_fsm->again_val_log2, LOG2_GAIN_SHIFT, 8 ) >> 8;
394 break;
395 default:
396 p_set->data.exposure_ratio = 64 * (uint32_t)p_fsm->integration_time_long / p_fsm->integration_time_short;
397 break;
398 }
399 } else {
400 p_set->data.integration_time_long = p_fsm->integration_time_long;
401 p_set->data.exposure_ratio = 64 * (uint32_t)p_fsm->integration_time_long / p_fsm->integration_time_short;
402 }
403
404
405 p_set->info.again_log2 = p_fsm->again_val_log2;
406 p_set->info.dgain_log2 = p_fsm->dgain_val_log2;
407 p_set->info.isp_dgain_log2 = p_fsm->isp_dgain_log2;
408 // update exposure for this frame
409 p_set->info.exposure_log2 = p_set->info.again_log2 + p_set->info.dgain_log2 + p_set->info.isp_dgain_log2;
410 p_set->info.exposure_log2 += acamera_log2_fixed_to_fixed( p_set->data.integration_time, 0, LOG2_GAIN_SHIFT );
411
412 p_set->data.frame_id_tracking = p_fsm->frame_id_tracking;
413 }
414
cmos_update_exposure_history(cmos_fsm_ptr_t p_fsm)415 void cmos_update_exposure_history( cmos_fsm_ptr_t p_fsm )
416 {
417 unsigned long irq_flags;
418 cmos_control_param_t *param = (cmos_control_param_t *)_GET_UINT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_CONTROL );
419 //uint32_t gain;
420 if ( p_fsm->exposure_hist_pos < 0 ) {
421 int pos;
422 fsm_param_sensor_info_t sensor_info;
423 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_SENSOR_INFO, NULL, 0, &sensor_info, sizeof( sensor_info ) );
424
425 p_fsm->exposure_hist_pos = 0;
426 // reset state
427 for ( pos = 0; pos <= sensor_info.integration_time_apply_delay; ++pos ) {
428 cmos_store_frame_exposure_set( p_fsm, cmos_get_frame_exposure_set( p_fsm, pos ) );
429 }
430 }
431
432 irq_flags = system_spinlock_lock( p_fsm->exp_lock );
433 cmos_store_frame_exposure_set( p_fsm, &( p_fsm->exp_next_set ) );
434 system_spinlock_unlock( p_fsm->exp_lock, irq_flags );
435
436 // display gains in control tool
437 if ( !param->global_manual_integration_time ) {
438 #if EXPOSURE_DRIVES_LONG_INTEGRATION_TIME
439 uint32_t wdr_mode = 0;
440
441 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_WDR_MODE, NULL, 0, &wdr_mode, sizeof( wdr_mode ) );
442
443 param->global_integration_time = ( ( ( wdr_mode == WDR_MODE_LINEAR ) ? p_fsm->integration_time_short : p_fsm->integration_time_long ) );
444 #else
445 param->global_integration_time = ( p_fsm->integration_time_short );
446 #endif
447 }
448 if ( !param->global_manual_sensor_analog_gain ) {
449 param->global_sensor_analog_gain = ( p_fsm->again_val_log2 >> ( LOG2_GAIN_SHIFT - 5 ) );
450 }
451 if ( !param->global_manual_sensor_digital_gain ) {
452 param->global_sensor_digital_gain = ( p_fsm->dgain_val_log2 >> ( LOG2_GAIN_SHIFT - 5 ) );
453 }
454 if ( !param->global_manual_isp_digital_gain ) {
455 param->global_isp_digital_gain = ( p_fsm->isp_dgain_log2 >> ( LOG2_GAIN_SHIFT - 5 ) );
456 }
457 }
458
cmos_mointor_frame_start(cmos_fsm_ptr_t p_fsm)459 static void cmos_mointor_frame_start( cmos_fsm_ptr_t p_fsm )
460 {
461 uint32_t cur_frame_id = acamera_fsm_util_get_cur_frame_id( &p_fsm->cmn );
462
463 /* CMOS FrameStart should be called for every frame */
464 if ( ( p_fsm->prev_fs_frame_id != 0 ) &&
465 ( p_fsm->prev_fs_frame_id + 1 != cur_frame_id ) ) {
466
467 fsm_param_mon_err_head_t mon_err;
468 mon_err.err_type = MON_TYPE_ERR_CMOS_FS_DELAY;
469 acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_MON_ERROR_REPORT, &mon_err, sizeof( mon_err ) );
470 LOG( LOG_ERR, "cmos_mon_fe: cur: %u, pre: %u.", cur_frame_id, p_fsm->prev_fs_frame_id );
471 }
472
473 p_fsm->prev_fs_frame_id = cur_frame_id;
474 }
475
476
cmos_mointor_frame_end(cmos_fsm_ptr_t p_fsm)477 static void cmos_mointor_frame_end( cmos_fsm_ptr_t p_fsm )
478 {
479
480 uint32_t irq_mask = acamera_isp_isp_global_interrupt_status_vector_read( p_fsm->cmn.isp_base );
481 if ( irq_mask & 0x1 ) {
482 fsm_param_mon_err_head_t mon_err;
483 mon_err.err_type = MON_TYPE_ERR_CMOS_UPDATE_NOT_IN_VB;
484 acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_MON_ERROR_REPORT, &mon_err, sizeof( mon_err ) );
485 }
486 }
487
cmos_move_exposure_history(cmos_fsm_ptr_t p_fsm)488 static void cmos_move_exposure_history( cmos_fsm_ptr_t p_fsm )
489 {
490 unsigned long irq_flags;
491
492 int pos = p_fsm->exposure_hist_pos + 1;
493 if ( pos >= ( sizeof( p_fsm->exposure_hist ) / sizeof( p_fsm->exposure_hist[0] ) ) ) // division by zero is checked
494 {
495 pos = 0;
496 }
497 p_fsm->exposure_hist_pos = pos;
498 fsm_param_sensor_info_t sensor_info;
499 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_SENSOR_INFO, NULL, 0, &sensor_info, sizeof( sensor_info ) );
500
501 irq_flags = system_spinlock_lock( p_fsm->exp_lock );
502 *cmos_get_frame_exposure_set( p_fsm, sensor_info.integration_time_apply_delay ) = p_fsm->exp_next_set;
503 system_spinlock_unlock( p_fsm->exp_lock, irq_flags );
504 }
505
cmos_fsm_process_interrupt(cmos_fsm_const_ptr_t p_fsm,uint8_t irq_event)506 void cmos_fsm_process_interrupt( cmos_fsm_const_ptr_t p_fsm, uint8_t irq_event )
507 {
508 if ( acamera_fsm_util_is_irq_event_ignored( (fsm_irq_mask_t *)( &p_fsm->mask ), irq_event ) )
509 return;
510
511 cmos_control_param_t *param = (cmos_control_param_t *)_GET_UINT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_CONTROL );
512 status_info_param_t *p_status_info = (status_info_param_t *)_GET_UINT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_STATUS_INFO );
513
514 uint32_t wdr_mode = 0;
515
516 fsm_param_sensor_info_t sensor_info;
517 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_SENSOR_INFO, NULL, 0, &sensor_info, sizeof( sensor_info ) );
518 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_WDR_MODE, NULL, 0, &wdr_mode, sizeof( wdr_mode ) );
519
520 switch ( irq_event ) {
521 case ACAMERA_IRQ_FRAME_START:
522 cmos_move_exposure_history( (cmos_fsm_ptr_t)p_fsm );
523 {
524 exposure_data_set_t exp_set = {0};
525 if ( ( wdr_mode == WDR_MODE_FS_LIN ) || ( ( wdr_mode == WDR_MODE_NATIVE ) && ( sensor_info.sensor_exp_number == 3 ) ) ) {
526 if ( sensor_info.sensor_exp_number == 1 ) {
527 exp_set.integration_time = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->data.actual_integration_time;
528 exp_set.exposure_ratio = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, 2 )->data.exposure_ratio;
529 if ( is_short_exposure_frame( p_fsm->cmn.isp_base ) == 0 ) {
530 ACAMERA_FSM2CTX_PTR( p_fsm )
531 ->stab.global_long_integration_time = exp_set.integration_time;
532 } else {
533 ACAMERA_FSM2CTX_PTR( p_fsm )
534 ->stab.global_short_integration_time = ( exp_set.integration_time );
535 }
536 exp_set.actual_integration_time = exp_set.integration_time;
537
538 } else if ( sensor_info.sensor_exp_number == 2 ) {
539 exp_set.integration_time = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->data.integration_time;
540 exp_set.integration_time_long = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->data.integration_time_long;
541 exp_set.exposure_ratio = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, 2 )->data.exposure_ratio;
542 ACAMERA_FSM2CTX_PTR( p_fsm )
543 ->stab.global_long_integration_time = ( exp_set.integration_time_long );
544 ACAMERA_FSM2CTX_PTR( p_fsm )
545 ->stab.global_short_integration_time = ( exp_set.integration_time );
546
547 } else if ( sensor_info.sensor_exp_number == 3 ) {
548 exp_set.integration_time = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->data.integration_time;
549 exp_set.integration_time_medium = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->data.integration_time_medium;
550 exp_set.integration_time_long = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->data.integration_time_long;
551 exp_set.exposure_ratio_short = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, 2 )->data.exposure_ratio_short;
552 exp_set.exposure_ratio_medium = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, 2 )->data.exposure_ratio_medium;
553 //LOG( LOG_ERR, " short %d medium %d long %d Rs %d Rm %d", exp_set.integration_time, exp_set.integration_time_medium, exp_set.integration_time_long, exp_set.exposure_ratio_short, exp_set.exposure_ratio_medium );
554
555 ACAMERA_FSM2CTX_PTR( p_fsm )
556 ->stab.global_long_integration_time = ( exp_set.integration_time_long );
557 ACAMERA_FSM2CTX_PTR( p_fsm )
558 ->stab.global_short_integration_time = ( exp_set.integration_time );
559
560 } else /* sensor_exp_number == 4 */ {
561 exp_set.integration_time = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->data.integration_time;
562 exp_set.integration_time_medium = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->data.integration_time_medium;
563 exp_set.integration_time_medium2 = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->data.integration_time_medium2;
564 exp_set.integration_time_long = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->data.integration_time_long;
565 exp_set.exposure_ratio_short = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, 2 )->data.exposure_ratio_short;
566 exp_set.exposure_ratio_medium = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, 2 )->data.exposure_ratio_medium;
567 exp_set.exposure_ratio_medium2 = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, 2 )->data.exposure_ratio_medium2;
568 //LOG( LOG_ERR, " short %d medium %d long %d Rs %d Rm %d", exp_set.integration_time, exp_set.integration_time_medium, exp_set.integration_time_long, exp_set.exposure_ratio_short, exp_set.exposure_ratio_medium );
569
570 ACAMERA_FSM2CTX_PTR( p_fsm )
571 ->stab.global_long_integration_time = ( exp_set.integration_time_long );
572 ACAMERA_FSM2CTX_PTR( p_fsm )
573 ->stab.global_short_integration_time = ( exp_set.integration_time );
574 }
575 } else {
576 exp_set.integration_time = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->data.integration_time;
577 ACAMERA_FSM2CTX_PTR( p_fsm )
578 ->stab.global_short_integration_time = ( exp_set.integration_time );
579
580 if ( sensor_info.sensor_exp_number == 1 ) {
581 exp_set.actual_integration_time = exp_set.integration_time;
582 exp_set.exposure_ratio = 64;
583
584 } else if ( sensor_info.sensor_exp_number == 2 ) {
585 exp_set.integration_time = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->data.integration_time;
586 exp_set.integration_time_long = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->data.integration_time_long;
587 exp_set.exposure_ratio = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, 2 )->data.exposure_ratio;
588
589 } else if ( sensor_info.sensor_exp_number == 3 ) {
590 exp_set.integration_time = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->data.integration_time;
591 exp_set.integration_time_medium = exp_set.integration_time;
592 exp_set.integration_time_long = exp_set.integration_time;
593 exp_set.exposure_ratio_short = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, 2 )->data.exposure_ratio_short;
594 exp_set.exposure_ratio_medium = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, 2 )->data.exposure_ratio_medium;
595
596 } else /* sensor_exp_number == 4 */ {
597 exp_set.integration_time = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, sensor_info.integration_time_apply_delay )->data.integration_time;
598 exp_set.integration_time_medium = exp_set.integration_time;
599 exp_set.integration_time_medium2 = exp_set.integration_time;
600 exp_set.integration_time_long = exp_set.integration_time;
601 exp_set.exposure_ratio_short = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, 2 )->data.exposure_ratio_short;
602 exp_set.exposure_ratio_medium = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, 2 )->data.exposure_ratio_medium;
603 exp_set.exposure_ratio_medium2 = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, 2 )->data.exposure_ratio_medium2;
604 }
605 }
606 exp_set.isp_dgain_log2 = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, 2 )->data.isp_dgain_log2;
607
608 // tracking integration time and isp_dgain separately?
609 exp_set.frame_id_tracking = cmos_get_frame_exposure_set( (cmos_fsm_ptr_t)p_fsm, 2 )->data.frame_id_tracking;
610
611 ( (cmos_fsm_ptr_t)p_fsm )->exp_write_set = exp_set;
612
613 if ( ( ACAMERA_FSM2CTX_PTR( p_fsm )->stab.global_freeze_firmware != 1 ) ) {
614 acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_SENSOR_UPDATE, NULL, 0 );
615
616 // frame_id should not be 0, at the beginning, it's initialized to 0 and we should skip it.
617 if ( ( p_fsm->prev_ae_frame_id_tracking != exp_set.frame_id_tracking ) && ( exp_set.frame_id_tracking != 0 ) ) {
618 fsm_param_mon_alg_flow_t ae_flow;
619
620 ( (cmos_fsm_ptr_t)p_fsm )->prev_ae_frame_id_tracking = exp_set.frame_id_tracking;
621
622 ae_flow.frame_id_tracking = exp_set.frame_id_tracking;
623 ae_flow.frame_id_current = acamera_fsm_util_get_cur_frame_id( &( (cmos_fsm_ptr_t)p_fsm )->cmn );
624 ae_flow.flow_state = MON_ALG_FLOW_STATE_APPLIED;
625 acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_MON_AE_FLOW, &ae_flow, sizeof( ae_flow ) );
626 }
627 }
628
629 // check antiflicker frequency value
630 int flicker_freq = (int)param->global_anti_flicker_frequency * 256;
631 if ( param->global_antiflicker_enable == 0 ) {
632 flicker_freq = 0;
633 }
634 if ( flicker_freq != p_fsm->flicker_freq ) {
635 ( (cmos_fsm_ptr_t)p_fsm )->flicker_freq = flicker_freq;
636 fsm_raise_event( p_fsm, event_id_antiflicker_changed );
637 }
638 }
639
640 p_status_info->sys_info.exposure_log2 = p_fsm->exposure_log2;
641 p_status_info->sys_info.total_gain_log2 = p_fsm->again_val_log2 + p_fsm->dgain_val_log2 + p_fsm->isp_dgain_log2;
642
643 cmos_mointor_frame_start( (cmos_fsm_ptr_t)p_fsm );
644
645 break;
646 case ACAMERA_IRQ_FRAME_END: {
647
648 if ( ( wdr_mode == WDR_MODE_FS_LIN ) && ( ACAMERA_FSM2CTX_PTR( p_fsm )->stab.global_manual_frame_stitch == 0 ) ) {
649
650 if ( sensor_info.sensor_exp_number == 4 ) {
651 acamera_isp_frame_stitch_svs_exposure_ratio_write( p_fsm->cmn.isp_base, p_fsm->exp_write_set.exposure_ratio_short );
652 acamera_isp_frame_stitch_ms_exposure_ratio_write( p_fsm->cmn.isp_base, p_fsm->exp_write_set.exposure_ratio_medium );
653 acamera_isp_frame_stitch_lm_exposure_ratio_write( p_fsm->cmn.isp_base, p_fsm->exp_write_set.exposure_ratio_medium2 );
654
655 int32_t R12 = p_fsm->exp_write_set.exposure_ratio_medium2; //long/medium ratio
656 int32_t R13 = ( R12 * (int32_t)p_fsm->exp_write_set.exposure_ratio_medium ) >> 6; //long/short ratio
657 int32_t R14 = ( R13 * (int32_t)p_fsm->exp_write_set.exposure_ratio_short ) >> 6; //long/very_short ratio
658
659 if ( R12 < 0 ) {
660 R12 = 1;
661 }
662 if ( R13 < 0 ) {
663 R13 = 1;
664 }
665 if ( R14 < 0 ) {
666 R14 = 1;
667 }
668
669 const int32_t SF2 = ( 262144 / R12 + 262144 / R13 + 262144 / R14 ) * 2048 / ( 4096 + 262144 / R12 + 262144 / R13 + 262144 / R14 );
670 const int32_t SF3 = ( 262144 / R13 + 262144 / R14 ) * 2048 / ( 262144 / R12 + 262144 / R13 + 262144 / R14 );
671 const int32_t SF4 = ( 262144 / R14 ) * 2048 / ( 262144 / R13 + 262144 / R14 );
672
673 acamera_isp_frame_stitch_mcoff_l_scaler_write( p_fsm->cmn.isp_base, (uint16_t)SF2 );
674 acamera_isp_frame_stitch_mcoff_lm_scaler_write( p_fsm->cmn.isp_base, (uint16_t)SF3 );
675 acamera_isp_frame_stitch_mcoff_lms_scaler_write( p_fsm->cmn.isp_base, (uint16_t)SF4 );
676
677 } else if ( sensor_info.sensor_exp_number == 3 ) {
678
679 acamera_isp_frame_stitch_ms_exposure_ratio_write( p_fsm->cmn.isp_base, p_fsm->exp_write_set.exposure_ratio_short );
680 acamera_isp_frame_stitch_lm_exposure_ratio_write( p_fsm->cmn.isp_base, p_fsm->exp_write_set.exposure_ratio_medium );
681 // mc off
682 // if(Exp == 2)
683 // param.SF2 = 1/(1 + R12);
684 // param.SF3 = 0;
685 // param.SF4 = 0;
686 // elseif(Exp == 3)
687 // param.SF2 = (1/R12 + 1/R13) / (1 + 1/R12 + 1/R13);
688 // param.SF3 = (1/R13)/(1/R12 + 1/R13);
689 // param.SF4 = 0;
690 // elseif(Exp == 4)
691 // param.SF2 = (1/R12 + 1/R13 + 1/R14)/(1 + 1/R12 + 1/R13 + 1/R14);
692 // param.SF3 = (1/R13 + 1/R14)/(1/R12 + 1/R13 + 1/R14);
693 // param.SF4 = (1/R14)/(1/R13 + 1/R14);
694
695 int32_t SF2, SF3, SF4; //U0.11 registers
696 int32_t R12, R13;
697 R12 = p_fsm->exp_write_set.exposure_ratio_medium; //long/medium ratio
698 R13 = ( ( int32_t )( p_fsm->exp_write_set.exposure_ratio_medium ) * ( int32_t )( p_fsm->exp_write_set.exposure_ratio_short ) ) >> 6; //long/short ratio
699 // printf("r12 %d r13 %d\n",(int)R12,(int)R13 );
700 // SF2 = round(((round(262144/R12) + round(262144/R13))*2048) / round((2^12 + round(262144/R12) + round(262144/R13))))
701
702 SF2 = ( ( 262144 / R12 + 262144 / R13 ) * 2048 ) / ( 4096 + 262144 / R12 + 262144 / R13 ); //U0.11
703 SF3 = ( ( 262144 / R13 ) * 2048 ) / ( 262144 / R12 + 262144 / R13 ); //U0.11
704 SF4 = 0;
705 acamera_isp_frame_stitch_mcoff_l_scaler_write( p_fsm->cmn.isp_base, (uint16_t)SF2 );
706 acamera_isp_frame_stitch_mcoff_lm_scaler_write( p_fsm->cmn.isp_base, (uint16_t)SF3 );
707 acamera_isp_frame_stitch_mcoff_lms_scaler_write( p_fsm->cmn.isp_base, (uint16_t)SF4 );
708
709 } else if ( sensor_info.sensor_exp_number == 2 ) {
710 int32_t SF2, R12; //U0.11 registers
711 R12 = p_fsm->exp_write_set.exposure_ratio;
712 SF2 = 262144 / ( 2048 + R12 );
713 acamera_isp_frame_stitch_lm_exposure_ratio_write( p_fsm->cmn.isp_base, p_fsm->exp_write_set.exposure_ratio );
714
715 acamera_isp_frame_stitch_mcoff_l_scaler_write( p_fsm->cmn.isp_base, (uint16_t)SF2 );
716 acamera_isp_frame_stitch_mcoff_lm_scaler_write( p_fsm->cmn.isp_base, (uint16_t)0 );
717 acamera_isp_frame_stitch_mcoff_lms_scaler_write( p_fsm->cmn.isp_base, (uint16_t)0 );
718 } else {
719 acamera_isp_frame_stitch_lm_exposure_ratio_write( p_fsm->cmn.isp_base, p_fsm->exp_write_set.exposure_ratio );
720 }
721 }
722
723 #if defined( ISP_HAS_AWB_MESH_NBP_FSM ) || defined( ISP_HAS_AWB_MANUAL_FSM )
724 uint32_t i;
725 int32_t isp_dgain_log2 = p_fsm->exp_write_set.isp_dgain_log2;
726
727 fsm_param_awb_info_t wb_info;
728 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_AWB_INFO, NULL, 0, &wb_info, sizeof( wb_info ) );
729
730 uint32_t gain;
731
732 gain = acamera_math_exp2( isp_dgain_log2, LOG2_GAIN_SHIFT, 8 );
733 acamera_isp_digital_gain_gain_write( p_fsm->cmn.isp_base, gain );
734
735 for ( i = 0; i < 4; ++i ) {
736 gain = acamera_math_exp2( wb_info.wb_log2[i], LOG2_GAIN_SHIFT, 8 );
737 ( (cmos_fsm_ptr_t)p_fsm )->wb[i] = gain > 0xFFF ? 0xFFF : (uint16_t)gain;
738 }
739
740 // Expansion of values to the full range
741 uint32_t bl[4] = {acamera_isp_sensor_offset_pre_shading_offset_00_read( p_fsm->cmn.isp_base ),
742 acamera_isp_sensor_offset_pre_shading_offset_01_read( p_fsm->cmn.isp_base ),
743 acamera_isp_sensor_offset_pre_shading_offset_10_read( p_fsm->cmn.isp_base ),
744 acamera_isp_sensor_offset_pre_shading_offset_11_read( p_fsm->cmn.isp_base )};
745 for ( i = 0; i < 4; ++i ) {
746 uint32_t mult = ( 256 * ( ( (uint32_t)1 << ACAMERA_ISP_SENSOR_OFFSET_PRE_SHADING_OFFSET_00_DATASIZE ) - 1 ) ) / ( ( ( (uint32_t)1 << ACAMERA_ISP_SENSOR_OFFSET_PRE_SHADING_OFFSET_00_DATASIZE ) - 1 ) - bl[i] );
747 ( (cmos_fsm_ptr_t)p_fsm )->wb[i] = ( ( ( uint32_t )( (cmos_fsm_ptr_t)p_fsm )->wb[i] ) * mult ) / 256;
748 }
749
750 acamera_isp_white_balance_gain_00_write( p_fsm->cmn.isp_base, ( (cmos_fsm_ptr_t)p_fsm )->wb[0] );
751 acamera_isp_white_balance_gain_01_write( p_fsm->cmn.isp_base, ( (cmos_fsm_ptr_t)p_fsm )->wb[1] );
752 acamera_isp_white_balance_gain_10_write( p_fsm->cmn.isp_base, ( (cmos_fsm_ptr_t)p_fsm )->wb[2] );
753 acamera_isp_white_balance_gain_11_write( p_fsm->cmn.isp_base, ( (cmos_fsm_ptr_t)p_fsm )->wb[3] );
754
755 if ( ACAMERA_FSM2CTX_PTR( p_fsm )->stab.global_manual_frame_stitch == 0 ) {
756
757 acamera_isp_frame_stitch_gain_r_write( p_fsm->cmn.isp_base, ( (cmos_fsm_ptr_t)p_fsm )->wb[0] );
758 acamera_isp_frame_stitch_gain_b_write( p_fsm->cmn.isp_base, ( (cmos_fsm_ptr_t)p_fsm )->wb[3] );
759
760 if ( acamera_isp_frame_stitch_mcoff_mode_enable_read( p_fsm->cmn.isp_base ) == 1 ) {
761 acamera_isp_frame_stitch_gain_r_write( p_fsm->cmn.isp_base, 65536 / ( ( (cmos_fsm_ptr_t)p_fsm )->wb[0] ) );
762 acamera_isp_frame_stitch_gain_b_write( p_fsm->cmn.isp_base, 65536 / ( ( (cmos_fsm_ptr_t)p_fsm )->wb[3] ) );
763 }
764 }
765
766 uint32_t cur_frame_id = acamera_fsm_util_get_cur_frame_id( &( (cmos_fsm_ptr_t)p_fsm )->cmn );
767
768 // "sensor_info.integration_time_apply_delay + 1" because the current frame_id is not so accurate.
769 if ( p_fsm->exp_write_set.frame_id_tracking && ( p_fsm->exp_write_set.frame_id_tracking != p_fsm->prev_dgain_frame_id ) &&
770 ( cur_frame_id - p_fsm->exp_write_set.frame_id_tracking > sensor_info.integration_time_apply_delay + 1 ) ) {
771 fsm_param_mon_err_head_t mon_err;
772 mon_err.err_type = MON_TYPE_ERR_CMOS_UPDATE_DGAIN_WRONG_TIMING;
773 mon_err.err_param = cur_frame_id - p_fsm->exp_write_set.frame_id_tracking - sensor_info.integration_time_apply_delay;
774 acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_MON_ERROR_REPORT, &mon_err, sizeof( mon_err ) );
775 ( (cmos_fsm_ptr_t)p_fsm )->prev_dgain_frame_id = p_fsm->exp_write_set.frame_id_tracking;
776 }
777
778 // frame_id should not be 0, at the beginning, it's initialized to 0 and we should skip it.
779 if ( ( p_fsm->prev_awb_frame_id_tracking != wb_info.result_gain_frame_id ) && ( wb_info.result_gain_frame_id != 0 ) ) {
780 fsm_param_mon_alg_flow_t awb_flow;
781
782 ( (cmos_fsm_ptr_t)p_fsm )->prev_awb_frame_id_tracking = wb_info.result_gain_frame_id;
783
784 awb_flow.frame_id_tracking = wb_info.result_gain_frame_id;
785 awb_flow.frame_id_current = cur_frame_id;
786 awb_flow.flow_state = MON_ALG_FLOW_STATE_APPLIED;
787 acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_MON_AWB_FLOW, &awb_flow, sizeof( awb_flow ) );
788 }
789
790 #endif //ISP_HAS_AWB_MESH_NBP_FSM
791
792 _process_fps_cnt( (fps_counter_t *)&p_fsm->fps_cnt );
793 }
794
795 cmos_mointor_frame_end( (cmos_fsm_ptr_t)p_fsm );
796
797 break;
798 }
799 }
800
cmos_inttime_update(cmos_fsm_ptr_t p_fsm)801 void cmos_inttime_update( cmos_fsm_ptr_t p_fsm )
802 {
803 int32_t int_time = 0;
804 cmos_control_param_t *param = (cmos_control_param_t *)_GET_UINT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_CONTROL );
805 if ( param->global_manual_integration_time == 0 ) {
806 int i;
807 int32_t exposure = 0, exp_target = p_fsm->exposure_log2;
808 if ( p_fsm->manual_gain_mode == 1 ) {
809 int_time = exp_target - acamera_log2_fixed_to_fixed( p_fsm->manual_gain, 8, LOG2_GAIN_SHIFT );
810 } else {
811 int32_t gain;
812 gain = cmos_get_manual_again_log2( p_fsm );
813 if ( gain >= 0 ) {
814 exp_target -= gain;
815 }
816 gain = cmos_get_manual_dgain_log2( p_fsm );
817 if ( gain >= 0 ) {
818 exp_target -= gain;
819 }
820 gain = cmos_get_manual_isp_dgain_log2( p_fsm );
821 if ( gain >= 0 ) {
822 exp_target -= gain;
823 }
824 if ( exp_target < 0 ) {
825 exp_target = 0;
826 }
827
828 for ( i = 0; i < SYSTEM_EXPOSURE_PARTITION_VALUE_COUNT; ++i ) {
829 int i_param = i & 1;
830 int32_t addon = p_fsm->exp_lut[i];
831
832 if ( i_param == EXPOSURE_PARTITION_INTEGRATION_TIME_INDEX ) {
833 if ( exposure + addon > exp_target ) {
834 addon = exp_target - exposure;
835 }
836 int_time += addon;
837 }
838 exposure += addon;
839 if ( exposure >= exp_target ) {
840 break;
841 }
842 }
843 if ( p_fsm->flicker_freq && !p_fsm->manual_gain_mode && param->global_antiflicker_enable ) {
844 fsm_param_sensor_info_t sensor_info;
845 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_SENSOR_INFO, NULL, 0, &sensor_info, sizeof( sensor_info ) );
846
847 uint32_t line_per_half_period = ( sensor_info.lines_per_second << 8 ) / ( p_fsm->flicker_freq * 2 ); // division by zero is checked
848 if ( line_per_half_period != 0 ) {
849 int32_t half_period_log2 = acamera_log2_fixed_to_fixed( line_per_half_period, 0, LOG2_GAIN_SHIFT );
850 if ( int_time < half_period_log2 ) {
851 int_time = MIN( exp_target, half_period_log2 );
852 }
853 }
854 }
855 }
856 }
857 cmos_alloc_integration_time( p_fsm, int_time );
858 }
859
cmos_analog_gain_update(cmos_fsm_ptr_t p_fsm)860 void cmos_analog_gain_update( cmos_fsm_ptr_t p_fsm )
861 {
862 int32_t target_gain = p_fsm->target_gain_log2;
863 cmos_control_param_t *param = (cmos_control_param_t *)_GET_UINT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_CONTROL );
864
865 uint32_t wdr_mode = 0;
866 if ( param->global_analog_gain_last_priority == 1 ) {
867 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_WDR_MODE, NULL, 0, &wdr_mode, sizeof( wdr_mode ) );
868
869 if ( wdr_mode == WDR_MODE_NATIVE || wdr_mode == WDR_MODE_FS_LIN || wdr_mode == WDR_MODE_LINEAR ) {
870 // automatic sensor digital gain goes before analog gain
871 if ( cmos_get_manual_dgain_log2( p_fsm ) < 0 ) // negative means it is not manual
872 {
873 p_fsm->dgain_val_log2 = cmos_alloc_sensor_digital_gain( p_fsm, target_gain );
874 target_gain -= p_fsm->dgain_val_log2;
875 }
876 // analog gain has reserve before achieving maximum
877 if ( cmos_get_manual_isp_dgain_log2( p_fsm ) < 0 ) // negative means it is not manual
878 {
879 int32_t max_again = (int32_t)param->global_max_sensor_analog_gain << ( LOG2_GAIN_SHIFT - 5 );
880 int32_t max_isp_gain = ( (int32_t)param->global_max_isp_digital_gain << ( LOG2_GAIN_SHIFT - 5 ) ) - ( 1 << LOG2_GAIN_SHIFT );
881 int32_t reserved_again = max_again - ( ( (int32_t)param->global_analog_gain_reserve ) << LOG2_GAIN_SHIFT );
882 if ( target_gain > reserved_again + max_isp_gain ) {
883 target_gain -= max_isp_gain;
884 } else if ( target_gain > reserved_again ) {
885 target_gain = reserved_again;
886 }
887 }
888 }
889 }
890 const int32_t again_accuracy = ANALOG_GAIN_ACCURACY;
891 int32_t gain = cmos_get_manual_again_log2( p_fsm );
892 if ( gain < 0 ) // negative means it is not manual
893 {
894 // We should set as maximum as possible analogue gain less than or equals target_gain
895 gain = target_gain - again_accuracy;
896 if ( gain < 0 ) {
897 gain = 0;
898 }
899 }
900 if (param->global_manual_sensor_analog_gain == 0) {
901 int32_t again = cmos_alloc_sensor_analog_gain( p_fsm, gain );
902 if ( !param->global_manual_sensor_analog_gain &&
903 ( again != p_fsm->again_val_log2 ) ) {
904 if ( ( gain > p_fsm->again_val_log2 - again_accuracy ) &&
905 ( gain < p_fsm->again_val_log2 + again_accuracy ) ) {
906 again = cmos_alloc_sensor_analog_gain( p_fsm, p_fsm->again_val_log2 );
907 }
908 }
909 p_fsm->again_val_log2 = again;
910 } else {
911 p_fsm->again_val_log2 = gain;
912 }
913 }
914
cmos_digital_gain_update(cmos_fsm_ptr_t p_fsm)915 void cmos_digital_gain_update( cmos_fsm_ptr_t p_fsm )
916 {
917
918 int32_t gain = cmos_get_manual_dgain_log2( p_fsm );
919 if ( gain < 0 ) // negative means it is not manual
920 {
921 // we should set the rest gain to make target_gain equals analogue_gain x digital_gain
922 gain = cmos_alloc_sensor_digital_gain( p_fsm, p_fsm->target_gain_log2 - p_fsm->again_val_log2 );
923 }
924 p_fsm->dgain_val_log2 = gain;
925 gain = cmos_get_manual_isp_dgain_log2( p_fsm );
926 if ( gain < 0 ) // negative means it is not manual
927 {
928 gain = cmos_alloc_isp_digital_gain( p_fsm, p_fsm->target_gain_log2 - p_fsm->again_val_log2 - p_fsm->dgain_val_log2 );
929 }
930 p_fsm->isp_dgain_log2 = gain;
931 }
932
get_quantised_integration_time(cmos_fsm_ptr_t p_fsm,uint32_t int_time)933 uint32_t get_quantised_integration_time( cmos_fsm_ptr_t p_fsm, uint32_t int_time )
934 {
935 if ( !p_fsm->flicker_freq || p_fsm->manual_gain_mode ) {
936 return int_time;
937 }
938
939 fsm_param_sensor_info_t sensor_info;
940 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_SENSOR_INFO, NULL, 0, &sensor_info, sizeof( sensor_info ) );
941
942 uint32_t line_per_half_period = ( sensor_info.lines_per_second << 8 ) / ( p_fsm->flicker_freq * 2 ); // division by zero is checked
943 if ( line_per_half_period != 0 && ( int_time >= line_per_half_period && int_time <= ( line_per_half_period << 2 ) ) ) {
944 uint32_t N = int_time / line_per_half_period; // division by zero is checked
945 if ( N < 1 ) {
946 N = 1;
947 }
948 return N * line_per_half_period;
949 } else {
950 return int_time;
951 }
952 }
953
get_quantised_long_integration_time(cmos_fsm_ptr_t p_fsm,uint32_t int_time,uint32_t max_int_time)954 uint32_t get_quantised_long_integration_time( cmos_fsm_ptr_t p_fsm, uint32_t int_time, uint32_t max_int_time )
955 {
956 fsm_param_sensor_info_t sensor_info;
957 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_SENSOR_INFO, NULL, 0, &sensor_info, sizeof( sensor_info ) );
958
959 if ( int_time < sensor_info.integration_time_min ) {
960 int_time = sensor_info.integration_time_min;
961 } else if ( int_time > max_int_time ) {
962 int_time = max_int_time;
963 }
964 return get_quantised_integration_time( p_fsm, int_time );
965 }
966
cmos_antiflicker_update(cmos_fsm_ptr_t p_fsm)967 void cmos_antiflicker_update( cmos_fsm_ptr_t p_fsm )
968 {
969 uint32_t integration_time_short = get_quantised_integration_time( p_fsm, p_fsm->integration_time_short );
970
971 if ( integration_time_short <= p_fsm->integration_time_short ) {
972 p_fsm->integration_time_short = integration_time_short;
973 } else {
974 // Very bright scene
975 #if OVEREXPOSE_TO_KEEP_ANTIFLICKER
976 uint32_t wdr_mode = 0;
977 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_WDR_MODE, NULL, 0, &wdr_mode, sizeof( wdr_mode ) );
978 //Only do overexpose to keep antiflicker in linear mode
979 if ( wdr_mode == WDR_MODE_LINEAR ) {
980 cmos_control_param_t *param = (cmos_control_param_t *)_GET_UINT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_CONTROL );
981 // if set manual integration time, do not adjust.
982 if ( param->global_manual_integration_time ) {
983 return;
984 }
985 if ( param->global_antiflicker_enable && p_fsm->integration_time_short < integration_time_short ) {
986 p_fsm->integration_time_short = integration_time_short; // division by zero is checked
987 }
988 }
989 #endif
990 }
991 }
992
cmos_long_exposure_update(cmos_fsm_ptr_t p_fsm)993 void cmos_long_exposure_update( cmos_fsm_ptr_t p_fsm )
994 {
995 fsm_param_sensor_int_time_t time;
996
997 fsm_param_sensor_info_t sensor_info;
998 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_SENSOR_INFO, NULL, 0, &sensor_info, sizeof( sensor_info ) );
999
1000 cmos_control_param_t *param = (cmos_control_param_t *)_GET_UINT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_CONTROL );
1001 uint32_t exposure_ratio, integration_time_long, integration_time_long_quant;
1002 uint32_t wdr_mode = 0;
1003
1004 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_WDR_MODE, NULL, 0, &wdr_mode, sizeof( wdr_mode ) );
1005
1006 if ( ( wdr_mode == WDR_MODE_FS_LIN ) || ( ( wdr_mode == WDR_MODE_NATIVE ) && ( sensor_info.sensor_exp_number == 3 ) ) ) {
1007 uint32_t integration_time_long_max = sensor_info.integration_time_long_max;
1008 if ( !integration_time_long_max ) {
1009 uint32_t integration_time_long_max = sensor_info.integration_time_limit;
1010
1011 if ( param->global_manual_max_integration_time && integration_time_long_max > param->global_max_integration_time ) {
1012 integration_time_long_max = param->global_max_integration_time;
1013 }
1014 }
1015 exposure_ratio = p_fsm->exposure_ratio_in;
1016 if ( exposure_ratio < 64 ) {
1017 exposure_ratio = 64;
1018 }
1019 #if EXPOSURE_DRIVES_LONG_INTEGRATION_TIME
1020 uint32_t min_integration_time_short = sensor_info.integration_time_min;
1021 // Inverse long and short exposure
1022 integration_time_long = p_fsm->integration_time_short;
1023 p_fsm->integration_time_short = ( (uint32_t)integration_time_long << 6 ) / exposure_ratio; // division by zero is checked
1024 if ( p_fsm->integration_time_short < min_integration_time_short ) {
1025 p_fsm->integration_time_short = min_integration_time_short;
1026 }
1027 uint32_t integration_time_max = sensor_info.integration_time_max;
1028 if ( p_fsm->integration_time_short > integration_time_max ) {
1029 p_fsm->integration_time_short = integration_time_max;
1030 }
1031 #else
1032 integration_time_long = (uint32_t)p_fsm->integration_time_short * exposure_ratio >> 6;
1033 if ( integration_time_long > 0xFFFF )
1034 integration_time_long = 0xFFFF;
1035 #endif
1036
1037 integration_time_long_quant = get_quantised_long_integration_time( p_fsm, integration_time_long, integration_time_long_max );
1038 #if EXPOSURE_DRIVES_LONG_INTEGRATION_TIME
1039 if ( integration_time_long < integration_time_long_quant ) {
1040 integration_time_long_quant = integration_time_long;
1041 }
1042 #endif
1043 if ( integration_time_long_quant > integration_time_long_max ) {
1044 integration_time_long_quant = integration_time_long_max;
1045 }
1046
1047 #if FILTER_LONG_INT_TIME
1048 //rotate the FIFO
1049 if ( ++p_fsm->long_it_hist.p > &( p_fsm->long_it_hist.v[FILTER_LONG_INT_TIME - 1] ) )
1050 p_fsm->long_it_hist.p = &( p_fsm->long_it_hist.v[0] );
1051 p_fsm->long_it_hist.sum -= *p_fsm->long_it_hist.p;
1052 *p_fsm->long_it_hist.p = integration_time_long_quant;
1053 p_fsm->long_it_hist.sum += *p_fsm->long_it_hist.p;
1054
1055 integration_time_long_quant = p_fsm->long_it_hist.sum / FILTER_LONG_INT_TIME; // division by zero is checked
1056 #endif
1057
1058 p_fsm->integration_time_long = integration_time_long_quant;
1059 if ( sensor_info.sensor_exp_number == 4 ) {
1060
1061 const uint32_t exposure_ratio_thresholded = exposure_ratio > 256 ? exposure_ratio / 2 : exposure_ratio;
1062 const uint32_t ratio_cube_root = acamera_math_exp2( acamera_log2_fixed_to_fixed( exposure_ratio_thresholded, 6, 16 ) / 3, 16, 6 );
1063 //LOG(LOG_CRIT, "ratio_cube_root: %d -> %d", exposure_ratio_thresholded, ratio_cube_root);
1064
1065 uint32_t integration_time_medium1 = p_fsm->integration_time_short * ratio_cube_root >> 6;
1066 uint32_t integration_time_medium2 = integration_time_medium1 * ratio_cube_root >> 6;
1067
1068 if ( integration_time_medium2 > integration_time_long_max ) {
1069 integration_time_medium2 = integration_time_long_max;
1070 }
1071 if ( integration_time_medium2 > p_fsm->integration_time_long ) {
1072 integration_time_medium2 = p_fsm->integration_time_long;
1073 }
1074 if ( integration_time_medium1 > integration_time_medium2 ) {
1075 integration_time_medium1 = integration_time_medium2;
1076 }
1077
1078 time.int_time = p_fsm->integration_time_short;
1079 time.int_time_M = integration_time_medium1;
1080 time.int_time_M2 = integration_time_medium2;
1081 time.int_time_L = p_fsm->integration_time_long;
1082
1083 acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_SENSOR_ALLOC_INTEGRATION_TIME, &time, sizeof( time ) );
1084
1085 // time is updated in above function, save it.
1086 p_fsm->integration_time_short = time.int_time;
1087 p_fsm->integration_time_medium = time.int_time_M;
1088 p_fsm->integration_time_medium2 = time.int_time_M2;
1089 p_fsm->integration_time_long = time.int_time_L;
1090
1091 } else if ( sensor_info.sensor_exp_number == 3 ) {
1092 uint32_t integration_time_medium;
1093 if ( exposure_ratio > 256 ) {
1094 //half ML ratio by two
1095 integration_time_medium = (uint32_t)p_fsm->integration_time_short * ( acamera_sqrt32( exposure_ratio ) << 1 ) >> 3;
1096 } else {
1097 integration_time_medium = (uint32_t)p_fsm->integration_time_short * acamera_sqrt32( exposure_ratio ) >> 3;
1098 }
1099 //integration_time_medium = (uint32_t)p_fsm->integration_time_short * acamera_sqrt32( exposure_ratio ) >> 3;
1100
1101 //LOG( LOG_ERR, "integration_time_medium %d exposure_ratio %d sqrt32( exposure_ratio ) %d", integration_time_medium, exposure_ratio/64, acamera_sqrt32( exposure_ratio )<<3 );
1102 if ( integration_time_medium > integration_time_long_max ) {
1103 integration_time_medium = integration_time_long_max;
1104 }
1105 if ( integration_time_medium > p_fsm->integration_time_long ) {
1106 integration_time_medium = p_fsm->integration_time_long;
1107 }
1108 p_fsm->integration_time_medium = (uint16_t)integration_time_medium;
1109
1110 time.int_time = p_fsm->integration_time_short;
1111 time.int_time_M = p_fsm->integration_time_medium;
1112 time.int_time_L = p_fsm->integration_time_long;
1113 //LOG( LOG_ERR, " short %d medium %d long %d", p_fsm->integration_time_short, p_fsm->integration_time_medium, p_fsm->integration_time_long );
1114
1115 acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_SENSOR_ALLOC_INTEGRATION_TIME, &time, sizeof( time ) );
1116
1117 // time is updated in above function, save it.
1118 p_fsm->integration_time_short = time.int_time;
1119 p_fsm->integration_time_medium = time.int_time_M;
1120 p_fsm->integration_time_long = time.int_time_L;
1121
1122 } else if ( sensor_info.sensor_exp_number == 2 ) {
1123 time.int_time = p_fsm->integration_time_short;
1124 time.int_time_L = p_fsm->integration_time_long;
1125
1126 acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_SENSOR_ALLOC_INTEGRATION_TIME, &time, sizeof( time ) );
1127
1128 // time is updated in above function, save it.
1129 p_fsm->integration_time_short = time.int_time;
1130 p_fsm->integration_time_long = time.int_time_L;
1131
1132 } else {
1133 time.int_time = is_short_exposure_frame( p_fsm->cmn.isp_base ) ? p_fsm->integration_time_short : p_fsm->integration_time_long;
1134
1135 acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_SENSOR_ALLOC_INTEGRATION_TIME, &time, sizeof( time ) );
1136
1137 // time is updated in above function, save it.
1138 if ( is_short_exposure_frame( p_fsm->cmn.isp_base ) )
1139 p_fsm->integration_time_short = time.int_time;
1140 else
1141 p_fsm->integration_time_long = time.int_time;
1142 }
1143
1144 p_fsm->exposure_ratio = ( uint16_t )( 64 * (uint32_t)p_fsm->integration_time_long / p_fsm->integration_time_short );
1145 } else {
1146 p_fsm->exposure_ratio = 64;
1147
1148 if ( sensor_info.sensor_exp_number == 4 ) {
1149
1150 time.int_time = p_fsm->integration_time_short;
1151 time.int_time_M = p_fsm->integration_time_short;
1152 time.int_time_M2 = p_fsm->integration_time_short;
1153 time.int_time_L = p_fsm->integration_time_short;
1154
1155 acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_SENSOR_ALLOC_INTEGRATION_TIME, &time, sizeof( time ) );
1156
1157 // NOTE: the value of 'p_fsm->integration_time_short' depends on the order
1158 // that sensor function modify the pointer values, I checked the some functions,
1159 // and found that the 3rd parameter will be modified at last, so we use the 3rd
1160 // parameter to save back into the 'p_fsm->integration_time_short' variable.
1161 p_fsm->integration_time_short = time.int_time_L;
1162
1163 } else if ( sensor_info.sensor_exp_number == 3 ) {
1164 time.int_time = p_fsm->integration_time_short;
1165 time.int_time_M = p_fsm->integration_time_short;
1166 time.int_time_L = p_fsm->integration_time_short;
1167
1168 acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_SENSOR_ALLOC_INTEGRATION_TIME, &time, sizeof( time ) );
1169
1170 // time is updated in above function, save it.
1171 p_fsm->integration_time_short = time.int_time_L;
1172
1173 } else if ( sensor_info.sensor_exp_number == 2 ) {
1174 time.int_time = p_fsm->integration_time_short;
1175 time.int_time_L = p_fsm->integration_time_short;
1176
1177 acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_SENSOR_ALLOC_INTEGRATION_TIME, &time, sizeof( time ) );
1178
1179 // time is updated in above function, save it.
1180 p_fsm->integration_time_short = time.int_time_L;
1181 } else {
1182 time.int_time = p_fsm->integration_time_short;
1183
1184 acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_SENSOR_ALLOC_INTEGRATION_TIME, &time, sizeof( time ) );
1185
1186 // time is updated in above function, save it.
1187 p_fsm->integration_time_short = time.int_time;
1188 }
1189 }
1190 }
1191
cmos_calc_target_gain(cmos_fsm_ptr_t p_fsm)1192 void cmos_calc_target_gain( cmos_fsm_ptr_t p_fsm )
1193 {
1194 int32_t target_gain_log2 = 0;
1195 if ( p_fsm->manual_gain_mode == 1 ) {
1196 target_gain_log2 = acamera_log2_fixed_to_fixed( p_fsm->manual_gain, 8, LOG2_GAIN_SHIFT );
1197 } else {
1198 #if EXPOSURE_DRIVES_LONG_INTEGRATION_TIME
1199 uint32_t wdr_mode = 0;
1200
1201 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_WDR_MODE, NULL, 0, &wdr_mode, sizeof( wdr_mode ) );
1202
1203 target_gain_log2 = p_fsm->exposure_log2 - acamera_log2_fixed_to_fixed( ( ( wdr_mode == WDR_MODE_LINEAR ) ? p_fsm->integration_time_short : p_fsm->integration_time_long ), 0, LOG2_GAIN_SHIFT );
1204 #else
1205 target_gain_log2 = p_fsm->exposure_log2 - acamera_log2_fixed_to_fixed( p_fsm->integration_time_short, 0, LOG2_GAIN_SHIFT );
1206 #endif
1207 }
1208
1209 if ( target_gain_log2 < 0 ) {
1210 target_gain_log2 = 0;
1211 }
1212 p_fsm->target_gain_step_log2 = target_gain_log2 - p_fsm->target_gain_log2;
1213 if ( p_fsm->target_gain_step_log2 < 0 ) {
1214 p_fsm->target_gain_step_log2 = -p_fsm->target_gain_step_log2;
1215 }
1216 p_fsm->target_gain_log2 = target_gain_log2;
1217 }
1218
cmos_set_exposure_target(cmos_fsm_ptr_t p_fsm,int32_t exposure_log2,uint32_t exposure_ratio)1219 void cmos_set_exposure_target( cmos_fsm_ptr_t p_fsm, int32_t exposure_log2, uint32_t exposure_ratio )
1220 {
1221 #if defined( ISP_HAS_DEFECT_PIXEL_FSM )
1222
1223 fsm_param_defect_pixel_info_t dp_info;
1224
1225 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_DEFECT_PIXEL_INFO, NULL, 0, &dp_info, sizeof( dp_info ) );
1226
1227 if ( !dp_info.hp_started )
1228 #endif
1229 {
1230
1231 uint32_t wdr_mode = 0;
1232
1233 fsm_param_sensor_info_t sensor_info;
1234 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_SENSOR_INFO, NULL, 0, &sensor_info, sizeof( sensor_info ) );
1235 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_WDR_MODE, NULL, 0, &wdr_mode, sizeof( wdr_mode ) );
1236
1237 // for HDR mode with one exposure we can set new exposure only every second frame
1238 if ( !( ( ( wdr_mode == WDR_MODE_FS_LIN ) ) && ( sensor_info.sensor_exp_number == 1 ) && !is_short_exposure_frame( p_fsm->cmn.isp_base ) ) ) {
1239 cmos_control_param_t *param_cmos = (cmos_control_param_t *)_GET_UINT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_CONTROL );
1240 p_fsm->exposure_log2 = exposure_log2;
1241 p_fsm->exposure_ratio_in = exposure_ratio;
1242 if ( p_fsm->exposure_ratio_in > (uint32_t)param_cmos->global_max_exposure_ratio * 64 ) {
1243
1244 p_fsm->exposure_ratio_in = param_cmos->global_max_exposure_ratio * 64;
1245 }
1246
1247 LOG( LOG_DEBUG, "Set exposure %d and exposure ratio %d", (unsigned int)exposure_log2, (unsigned int)exposure_ratio );
1248 }
1249 }
1250 #ifdef ISP_HAS_SENSOR_FSM
1251 #if USER_MODULE
1252 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_MAX_EXPOSURE_LOG2, NULL, 0, &p_fsm->max_exposure_log2, sizeof( p_fsm->max_exposure_log2 ) );
1253 #else
1254 cmos_control_param_t *param = (cmos_control_param_t *)_GET_UINT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_CMOS_CONTROL );
1255
1256 fsm_param_sensor_info_t sensor_info;
1257 acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_SENSOR_INFO, NULL, 0, &sensor_info, sizeof( sensor_info ) );
1258
1259 param->global_max_sensor_analog_gain = MIN( param->global_max_sensor_analog_gain, sensor_info.again_log2_max >> ( LOG2_GAIN_SHIFT - 5 ) );
1260 param->global_max_sensor_digital_gain = MIN( param->global_max_sensor_digital_gain, sensor_info.dgain_log2_max >> ( LOG2_GAIN_SHIFT - 5 ) );
1261 param->global_max_integration_time = MIN( param->global_max_integration_time, sensor_info.integration_time_limit );
1262
1263
1264 int32_t max_again_log2 = MIN( sensor_info.again_log2_max, (int32_t)param->global_max_sensor_analog_gain << ( LOG2_GAIN_SHIFT - 5 ) );
1265 int32_t max_dgain_log2 = MIN( sensor_info.dgain_log2_max, (int32_t)param->global_max_sensor_digital_gain << ( LOG2_GAIN_SHIFT - 5 ) );
1266 int32_t max_isp_gain_log2 = MIN( p_fsm->maximum_isp_digital_gain, (int32_t)param->global_max_isp_digital_gain << ( LOG2_GAIN_SHIFT - 5 ) );
1267 int32_t max_integration_time_log2 = acamera_log2_fixed_to_fixed( sensor_info.integration_time_limit, 0, LOG2_GAIN_SHIFT );
1268 p_fsm->max_exposure_log2 = max_again_log2 + max_dgain_log2 + max_isp_gain_log2 + max_integration_time_log2;
1269 #endif // #if USER_MODULE
1270 #endif
1271 }
1272
cmos_deinit(cmos_fsm_ptr_t p_fsm)1273 void cmos_deinit( cmos_fsm_ptr_t p_fsm )
1274 {
1275 system_spinlock_destroy( p_fsm->exp_lock );
1276 }
1277