• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_firmware_api.h"
21 #include "acamera_fw.h"
22 #include "monitor_fsm.h"
23 
24 #ifdef LOG_MODULE
25 #undef LOG_MODULE
26 #define LOG_MODULE LOG_MODULE_MONITOR
27 #endif
28 
monitor_initialize(monitor_fsm_ptr_t p_fsm)29 void monitor_initialize( monitor_fsm_ptr_t p_fsm )
30 {
31     p_fsm->mask.repeat_irq_mask = ACAMERA_IRQ_MASK( ACAMERA_IRQ_FRAME_END );
32     monitor_request_interrupt( p_fsm, p_fsm->mask.repeat_irq_mask );
33 }
34 
monitor_handle_reset_error_report(monitor_fsm_ptr_t p_fsm,uint32_t err_type)35 void monitor_handle_reset_error_report( monitor_fsm_ptr_t p_fsm, uint32_t err_type )
36 {
37     switch ( err_type ) {
38     case MON_TYPE_ERR_CALIBRATION_LUT_NULL:
39         p_fsm->mon_info_cali.err_cnt_calibration_lut_null = 0;
40         p_fsm->mon_info_cali.err_param_calibration_lut_null_idx = 0;
41         break;
42 
43     case MON_TYPE_ERR_CMOS_FS_DELAY:
44         p_fsm->mon_info_cmos.err_cnt_cmos_fs_delay = 0;
45         break;
46 
47     case MON_TYPE_ERR_CMOS_UPDATE_NOT_IN_VB:
48         p_fsm->mon_info_cmos.err_cnt_cmos_fe_update_not_in_vb = 0;
49         break;
50 
51     case MON_TYPE_ERR_CMOS_UPDATE_DGAIN_WRONG_TIMING:
52         p_fsm->mon_info_cmos.err_cnt_cmos_dgain_update_wrong_timing = 0;
53         p_fsm->mon_info_cmos.err_cmos_dgain_update_wrong_timing_diff = 0;
54         break;
55 
56     case MON_TYPE_ERR_IRIDIX_UPDATE_NOT_IN_VB:
57         p_fsm->mon_info_iridix.err_cnt_iridix_fe_update_not_in_vb = 0;
58         break;
59 
60     default:
61         LOG( LOG_ERR, "MON: Invalid err_type: %d", err_type );
62         break;
63     }
64 }
65 
monitor_handle_error_report(monitor_fsm_ptr_t p_fsm,fsm_param_mon_err_head_t * p_mon_err_head)66 void monitor_handle_error_report( monitor_fsm_ptr_t p_fsm, fsm_param_mon_err_head_t *p_mon_err_head )
67 {
68 
69     switch ( p_mon_err_head->err_type ) {
70     case MON_TYPE_ERR_CALIBRATION_LUT_NULL:
71         p_fsm->mon_info_cali.err_cnt_calibration_lut_null++;
72 
73         // avoid overflow
74         if ( 0 == p_fsm->mon_info_cali.err_cnt_calibration_lut_null ) {
75             p_fsm->mon_info_cali.err_cnt_calibration_lut_null = 1;
76         }
77 
78         p_fsm->mon_info_cali.err_param_calibration_lut_null_idx = p_mon_err_head->err_param;
79 
80         break;
81 
82     case MON_TYPE_ERR_CMOS_FS_DELAY:
83         p_fsm->mon_info_cmos.err_cnt_cmos_fs_delay++;
84         break;
85 
86     case MON_TYPE_ERR_CMOS_UPDATE_NOT_IN_VB:
87         p_fsm->mon_info_cmos.err_cnt_cmos_fe_update_not_in_vb++;
88         break;
89 
90     case MON_TYPE_ERR_CMOS_UPDATE_DGAIN_WRONG_TIMING:
91         p_fsm->mon_info_cmos.err_cnt_cmos_dgain_update_wrong_timing++;
92         p_fsm->mon_info_cmos.err_cmos_dgain_update_wrong_timing_diff = p_mon_err_head->err_param;
93         break;
94 
95     case MON_TYPE_ERR_IRIDIX_UPDATE_NOT_IN_VB:
96         p_fsm->mon_info_iridix.err_cnt_iridix_fe_update_not_in_vb++;
97         break;
98 
99     default:
100         LOG( LOG_ERR, "MON: Invalid err_type: %d", p_mon_err_head->err_type );
101         break;
102     }
103 }
104 
monitor_get_error_report(monitor_fsm_ptr_t p_fsm,uint32_t err_type,uint32_t * err_param)105 void monitor_get_error_report( monitor_fsm_ptr_t p_fsm, uint32_t err_type, uint32_t *err_param )
106 {
107 
108     switch ( err_type ) {
109     case MON_TYPE_ERR_CALIBRATION_LUT_NULL:
110         *err_param = p_fsm->mon_info_cali.err_param_calibration_lut_null_idx;
111         break;
112 
113     case MON_TYPE_ERR_CMOS_FS_DELAY:
114         *err_param = p_fsm->mon_info_cmos.err_cnt_cmos_fs_delay;
115         break;
116 
117     case MON_TYPE_ERR_CMOS_UPDATE_NOT_IN_VB:
118         *err_param = p_fsm->mon_info_cmos.err_cnt_cmos_fe_update_not_in_vb;
119         break;
120 
121     case MON_TYPE_ERR_CMOS_UPDATE_DGAIN_WRONG_TIMING:
122         *err_param = ( p_fsm->mon_info_cmos.err_cmos_dgain_update_wrong_timing_diff << 16 ) |
123                      ( p_fsm->mon_info_cmos.err_cnt_cmos_dgain_update_wrong_timing );
124         break;
125 
126     case MON_TYPE_ERR_IRIDIX_UPDATE_NOT_IN_VB:
127         *err_param = p_fsm->mon_info_iridix.err_cnt_iridix_fe_update_not_in_vb;
128         break;
129 
130     default:
131         LOG( LOG_ERR, "MON: Invalid err_type: %d", err_type );
132         break;
133     }
134 }
135 
monitor_dump_alg_state_arr(mon_alg_info_t * p_mon_info)136 static void monitor_dump_alg_state_arr( mon_alg_info_t *p_mon_info )
137 {
138     uint32_t j;
139     for ( j = 0; j < ARR_SIZE( p_mon_info->alg_state_arr ); j++ ) {
140         LOG( LOG_INFO, "%d). using: %d, frmae_id: %d, in->out->apply: %d->%d->%d.",
141              j,
142              p_mon_info->alg_state_arr[j].item_is_using,
143              p_mon_info->alg_state_arr[j].frame_id_tracking,
144              p_mon_info->alg_state_arr[j].frame_id_alg_state_input,
145              p_mon_info->alg_state_arr[j].frame_id_alg_state_output,
146              p_mon_info->alg_state_arr[j].frame_id_alg_state_apply );
147     }
148 }
149 
monitor_handle_alg_flow(monitor_fsm_ptr_t p_fsm,mon_alg_info_t * p_mon_info,fsm_param_mon_alg_flow_t * p_flow)150 void monitor_handle_alg_flow( monitor_fsm_ptr_t p_fsm, mon_alg_info_t *p_mon_info, fsm_param_mon_alg_flow_t *p_flow )
151 {
152     uint32_t i;
153 
154     if ( MON_ALG_FLOW_STATE_START == p_flow->flow_state ) {
155         i = p_mon_info->alg_arr_write_pos;
156 
157         if ( p_mon_info->alg_state_arr[i].item_is_using ) {
158             LOG( LOG_DEBUG, "MON_ALG_FLOW %s: overwrite frame: %d, pos: %d.", p_mon_info->alg_name, p_mon_info->alg_state_arr[i].frame_id_tracking, i );
159             // monitor_dump_alg_state_arr(p_mon_info);
160         }
161 
162         p_mon_info->alg_state_arr[i].item_is_using = 1;
163         p_mon_info->alg_state_arr[i].frame_id_tracking = p_flow->frame_id_tracking;
164         p_mon_info->alg_state_arr[i].frame_id_alg_state_input = p_flow->frame_id_current;
165 
166         p_mon_info->alg_arr_write_pos++;
167 
168         // wrap to the beginning
169         if ( p_mon_info->alg_arr_write_pos >= ARR_SIZE( p_mon_info->alg_state_arr ) )
170             p_mon_info->alg_arr_write_pos = 0;
171 
172     } else {
173 
174         for ( i = 0; i < ARR_SIZE( p_mon_info->alg_state_arr ); i++ ) {
175             if ( p_mon_info->alg_state_arr[i].item_is_using && ( p_mon_info->alg_state_arr[i].frame_id_tracking == p_flow->frame_id_tracking ) )
176                 break;
177         }
178 
179         if ( i >= ARR_SIZE( p_mon_info->alg_state_arr ) ) {
180             LOG( LOG_ERR, "MON_ALG_FLOW %s: Error: can't find frame: %d for state: %d.", p_mon_info->alg_name, p_flow->frame_id_tracking, p_flow->flow_state );
181             monitor_dump_alg_state_arr( p_mon_info );
182 
183             return;
184         }
185 
186         if ( MON_ALG_FLOW_STATE_OUTPUT_READY == p_flow->flow_state ) {
187             p_mon_info->alg_state_arr[i].frame_id_alg_state_output = p_flow->frame_id_current;
188 
189             // calculate FramePerTime
190             if ( p_mon_info->alg_fpt_prev_out_id ) {
191                 uint32_t fpt = p_flow->frame_id_current - p_mon_info->alg_fpt_prev_out_id;
192 
193                 p_mon_info->alg_fpt_cur = fpt;
194                 if ( fpt < p_mon_info->alg_fpt_min ) {
195                     p_mon_info->alg_fpt_min = fpt;
196                     LOG( LOG_ERR, "MON: %s: new min fpt: %d", p_mon_info->alg_name, fpt );
197                 }
198 
199                 if ( fpt > p_mon_info->alg_fpt_max ) {
200                     p_mon_info->alg_fpt_max = fpt;
201                     LOG( LOG_ERR, "MON: %s: new max fpt: %d", p_mon_info->alg_name, fpt );
202                 }
203             } else {
204                 // Firt Frame: init values
205                 p_mon_info->alg_fpt_min = 0xFFFF;
206                 p_mon_info->alg_fpt_max = 0;
207             }
208 
209             p_mon_info->alg_fpt_prev_out_id = p_flow->frame_id_current;
210 
211         } else if ( MON_ALG_FLOW_AE_STATE_END == p_flow->flow_state ) {
212 
213 
214             mon_alg_item_t *p_item = &( p_mon_info->alg_state_arr[i] );
215             p_item->frame_id_alg_state_apply = p_flow->frame_id_current;
216 
217             uint32_t item_delay_in2out = p_item->frame_id_alg_state_output - p_item->frame_id_alg_state_input;
218             uint32_t item_delay_out2apply = p_item->frame_id_alg_state_apply - p_item->frame_id_alg_state_output;
219 
220             if ( ( item_delay_in2out > 5 ) || ( item_delay_out2apply > 5 ) ) {
221                 monitor_dump_alg_state_arr( p_mon_info );
222             }
223 
224             p_item->item_is_using = 0;
225             // memset(p_item, 0, sizeof(*p_item));
226 
227 
228             p_mon_info->alg_delay_in2out_cur = item_delay_in2out;
229             p_mon_info->alg_delay_out2apply_cur = item_delay_out2apply;
230 
231             p_mon_info->mon_alg_frame_count++;
232 
233             // First frame
234             if ( 1 == p_mon_info->mon_alg_frame_count ) {
235                 p_mon_info->alg_delay_in2out_min = item_delay_in2out;
236                 p_mon_info->alg_delay_in2out_max = item_delay_in2out;
237 
238                 p_mon_info->alg_delay_out2apply_min = item_delay_out2apply;
239                 p_mon_info->alg_delay_out2apply_max = item_delay_out2apply;
240             } else {
241                 if ( item_delay_in2out < p_mon_info->alg_delay_in2out_min )
242                     p_mon_info->alg_delay_in2out_min = item_delay_in2out;
243 
244                 if ( item_delay_in2out > p_mon_info->alg_delay_in2out_max )
245                     p_mon_info->alg_delay_in2out_max = item_delay_in2out;
246 
247                 if ( item_delay_out2apply < p_mon_info->alg_delay_out2apply_min )
248                     p_mon_info->alg_delay_out2apply_min = item_delay_out2apply;
249 
250                 if ( item_delay_out2apply > p_mon_info->alg_delay_out2apply_max )
251                     p_mon_info->alg_delay_out2apply_max = item_delay_out2apply;
252             }
253         }
254     }
255 }
256 
monitor_set_alg_status(monitor_fsm_ptr_t p_fsm,mon_alg_info_t * p_mon_info,fsm_param_mon_status_head_t * p_status)257 void monitor_set_alg_status( monitor_fsm_ptr_t p_fsm, mon_alg_info_t *p_mon_info, fsm_param_mon_status_head_t *p_status )
258 {
259     switch ( p_status->status_type ) {
260     case MON_TYPE_STATUS_ALG_STATUS_RESET:
261         LOG( LOG_ERR, "MON: %s: reset param: %d", p_mon_info->alg_name, p_status->status_param );
262 
263         if ( p_status->status_param ) {
264             p_mon_info->alg_reset_status = 1;
265 
266             // Reset to 0xFFFFFFFF which is an invalid value
267             p_mon_info->alg_delay_in2out_min = 0xFFFFFFFF;
268             p_mon_info->alg_delay_in2out_cur = 0xFFFFFFFF;
269             p_mon_info->alg_delay_in2out_max = 0xFFFFFFFF;
270             p_mon_info->alg_delay_out2apply_min = 0xFFFFFFFF;
271             p_mon_info->alg_delay_out2apply_cur = 0xFFFFFFFF;
272             p_mon_info->alg_delay_out2apply_max = 0xFFFFFFFF;
273             p_mon_info->alg_fpt_min = 0xFFFF;
274             p_mon_info->alg_fpt_cur = 0;
275             p_mon_info->alg_fpt_max = 0;
276             p_mon_info->mon_alg_frame_count = 0;
277 
278             memset( p_mon_info->alg_state_arr, 0, sizeof( p_mon_info->alg_state_arr ) );
279             p_mon_info->alg_arr_write_pos = 0;
280 
281             p_mon_info->alg_reset_status = 0;
282         }
283         break;
284     default:
285         LOG( LOG_ERR, "MON: Invalid status_type: %d", p_status->status_type );
286         break;
287     }
288 }
289 
monitor_get_alg_status(monitor_fsm_ptr_t p_fsm,mon_alg_info_t * p_mon_info,uint32_t status_type,uint32_t * status)290 void monitor_get_alg_status( monitor_fsm_ptr_t p_fsm, mon_alg_info_t *p_mon_info, uint32_t status_type, uint32_t *status )
291 {
292     switch ( status_type ) {
293     case MON_TYPE_STATUS_ALG_DELAY_IN2OUT_MIN:
294         *status = p_mon_info->alg_delay_in2out_min;
295         break;
296 
297     case MON_TYPE_STATUS_ALG_DELAY_IN2OUT_CUR:
298         *status = p_mon_info->alg_delay_in2out_cur;
299         break;
300 
301     case MON_TYPE_STATUS_ALG_DELAY_IN2OUT_MAX:
302         *status = p_mon_info->alg_delay_in2out_max;
303         break;
304 
305     case MON_TYPE_STATUS_ALG_DELAY_OUT2APPLY_MIN:
306         *status = p_mon_info->alg_delay_out2apply_min;
307         break;
308 
309     case MON_TYPE_STATUS_ALG_DELAY_OUT2APPLY_CUR:
310         *status = p_mon_info->alg_delay_out2apply_cur;
311         break;
312 
313     case MON_TYPE_STATUS_ALG_DELAY_OUT2APPLY_MAX:
314         *status = p_mon_info->alg_delay_out2apply_max;
315         break;
316 
317     case MON_TYPE_STATUS_ALG_FPT_MIN:
318         *status = p_mon_info->alg_fpt_min;
319         break;
320 
321     case MON_TYPE_STATUS_ALG_FPT_CUR:
322         *status = p_mon_info->alg_fpt_cur;
323         break;
324 
325     case MON_TYPE_STATUS_ALG_FPT_MAX:
326         *status = p_mon_info->alg_fpt_max;
327         break;
328 
329     case MON_TYPE_STATUS_ALG_STATUS_RESET:
330         *status = p_mon_info->alg_reset_status;
331         break;
332 
333     default:
334         LOG( LOG_ERR, "MON: Invalid status_type: %d", status_type );
335         break;
336     }
337 }
338