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