1 /*
2 * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <sys/ioctl.h>
22 #include <poll.h>
23 #include <sys/time.h>
24 #include <fcntl.h>
25 #include <errno.h>
26 #include <pthread.h>
27 #include <math.h>
28 #include <unistd.h>
29 #include <signal.h>
30 #include <sys/prctl.h>
31 #include "sample_comm.h"
32
33 #ifdef __cplusplus
34 #if __cplusplus
35 extern "C" {
36 #endif
37 #endif /* End of #ifdef __cplusplus */
38
39 #define MAX_SENSOR_NUM 2
40 #define ISP_MAX_DEV_NUM 4
41 #define ISP_THREAD_NAME_LEN 20
42
43 static pthread_t g_IspPid[ISP_MAX_PIPE_NUM] = {0};
44 static HI_U32 g_au32IspSnsId[ISP_MAX_DEV_NUM] = { 0, 1 };
45
46 SAMPLE_SNS_TYPE_E g_enSnsType[MAX_SENSOR_NUM] = {
47 SENSOR0_TYPE,
48 SENSOR1_TYPE
49 };
50
51 ISP_PUB_ATTR_S ISP_PUB_ATTR_IMX335_MIPI_5M_30FPS = {
52 { 0, 0, IMG_5M_WIDTH, IMG_5M_HEIGHT },
53 { SENSOR_5M_WIDTH, SENSOR_5M_HEIGHT },
54 FPS_30,
55 BAYER_RGGB,
56 WDR_MODE_NONE,
57 0,
58 };
59
60 ISP_PUB_ATTR_S ISP_PUB_ATTR_IMX335_MIPI_5M_30FPS_WDR2TO1 = {
61 { 0, 0, IMG_5M_WIDTH, IMG_5M_HEIGHT },
62 { SENSOR_5M_WIDTH, SENSOR_5M_HEIGHT },
63 FPS_30,
64 BAYER_RGGB,
65 WDR_MODE_2To1_LINE,
66 0,
67 };
68
69 ISP_PUB_ATTR_S ISP_PUB_ATTR_IMX335_MIPI_4M_30FPS = {
70 { 0, 0, IMG_4M_WIDTH, IMG_4M_HEIGHT },
71 { SENSOR_5M_WIDTH, SENSOR_5M_HEIGHT },
72 FPS_30,
73 BAYER_RGGB,
74 WDR_MODE_NONE,
75 0,
76 };
77
78 ISP_PUB_ATTR_S ISP_PUB_ATTR_IMX335_MIPI_4M_30FPS_WDR2TO1 = {
79 { 0, 0, IMG_4M_WIDTH, IMG_4M_HEIGHT },
80 { SENSOR_5M_WIDTH, SENSOR_5M_HEIGHT },
81 FPS_30,
82 BAYER_RGGB,
83 WDR_MODE_2To1_LINE,
84 0,
85 };
86
SAMPLE_COMM_ISP_GetIspAttrBySns(SAMPLE_SNS_TYPE_E enSnsType,ISP_PUB_ATTR_S * pstPubAttr)87 HI_S32 SAMPLE_COMM_ISP_GetIspAttrBySns(SAMPLE_SNS_TYPE_E enSnsType, ISP_PUB_ATTR_S *pstPubAttr)
88 {
89 if (pstPubAttr == NULL) {
90 SAMPLE_PRT("null pointer\n");
91 return HI_FAILURE;
92 }
93 switch (enSnsType) {
94 case SONY_IMX335_MIPI_5M_30FPS_12BIT:
95 (HI_VOID)memcpy_s(pstPubAttr, sizeof(ISP_PUB_ATTR_S), &ISP_PUB_ATTR_IMX335_MIPI_5M_30FPS,
96 sizeof(ISP_PUB_ATTR_S));
97 break;
98
99 case SONY_IMX335_MIPI_4M_30FPS_12BIT:
100 (HI_VOID)memcpy_s(pstPubAttr, sizeof(ISP_PUB_ATTR_S), &ISP_PUB_ATTR_IMX335_MIPI_4M_30FPS,
101 sizeof(ISP_PUB_ATTR_S));
102 break;
103
104 case SONY_IMX335_MIPI_5M_30FPS_10BIT_WDR2TO1:
105 (HI_VOID)memcpy_s(pstPubAttr, sizeof(ISP_PUB_ATTR_S), &ISP_PUB_ATTR_IMX335_MIPI_5M_30FPS_WDR2TO1,
106 sizeof(ISP_PUB_ATTR_S));
107 break;
108
109 case SONY_IMX335_MIPI_4M_30FPS_10BIT_WDR2TO1:
110 (HI_VOID)memcpy_s(pstPubAttr, sizeof(ISP_PUB_ATTR_S), &ISP_PUB_ATTR_IMX335_MIPI_4M_30FPS_WDR2TO1,
111 sizeof(ISP_PUB_ATTR_S));
112 break;
113
114 default:
115 (HI_VOID)memcpy_s(pstPubAttr, sizeof(ISP_PUB_ATTR_S), &ISP_PUB_ATTR_IMX335_MIPI_4M_30FPS,
116 sizeof(ISP_PUB_ATTR_S));
117 break;
118 }
119
120 return HI_SUCCESS;
121 }
122
SAMPLE_COMM_ISP_GetSnsObj(HI_U32 u32SnsId)123 static ISP_SNS_OBJ_S *SAMPLE_COMM_ISP_GetSnsObj(HI_U32 u32SnsId)
124 {
125 SAMPLE_SNS_TYPE_E enSnsType;
126
127 enSnsType = g_enSnsType[u32SnsId];
128 switch (enSnsType) {
129 case SONY_IMX335_MIPI_5M_30FPS_12BIT:
130 case SONY_IMX335_MIPI_5M_30FPS_10BIT_WDR2TO1:
131 case SONY_IMX335_MIPI_4M_30FPS_12BIT:
132 case SONY_IMX335_MIPI_4M_30FPS_10BIT_WDR2TO1:
133 return &stSnsImx335Obj;
134
135 default:
136 return HI_NULL;
137 }
138 }
139
SAMPLE_COMM_ISP_Thread(void * param)140 static void *SAMPLE_COMM_ISP_Thread(void *param)
141 {
142 HI_S32 s32Ret;
143 ISP_DEV IspDev;
144 HI_CHAR szThreadName[ISP_THREAD_NAME_LEN];
145
146 IspDev = (ISP_DEV)(HI_UINTPTR_T)param;
147 s32Ret = snprintf_s(szThreadName, ISP_THREAD_NAME_LEN, ISP_THREAD_NAME_LEN - 1, "ISP%d_RUN", IspDev);
148 if (s32Ret < 0) {
149 SAMPLE_PRT("snprintf_s err !\n");
150 return NULL;
151 }
152
153 prctl(PR_SET_NAME, szThreadName, 0, 0, 0);
154
155 SAMPLE_PRT("ISP Dev %d running !\n", IspDev);
156 s32Ret = HI_MPI_ISP_Run(IspDev);
157 if (s32Ret != HI_SUCCESS) {
158 SAMPLE_PRT("HI_MPI_ISP_Run failed with %#x!\n", s32Ret);
159 }
160
161 return NULL;
162 }
163
SAMPLE_COMM_ISP_Aelib_Callback(ISP_DEV IspDev)164 HI_S32 SAMPLE_COMM_ISP_Aelib_Callback(ISP_DEV IspDev)
165 {
166 ALG_LIB_S stAeLib;
167
168 stAeLib.s32Id = IspDev;
169 (HI_VOID)strncpy_s(stAeLib.acLibName, sizeof(HI_AE_LIB_NAME) + 1, HI_AE_LIB_NAME, sizeof(HI_AE_LIB_NAME));
170 CHECK_RET(HI_MPI_AE_Register(IspDev, &stAeLib), "aelib register call back");
171 return HI_SUCCESS;
172 }
173
SAMPLE_COMM_ISP_Aelib_UnCallback(ISP_DEV IspDev)174 HI_S32 SAMPLE_COMM_ISP_Aelib_UnCallback(ISP_DEV IspDev)
175 {
176 ALG_LIB_S stAeLib;
177
178 stAeLib.s32Id = IspDev;
179 (HI_VOID)strncpy_s(stAeLib.acLibName, sizeof(HI_AE_LIB_NAME) + 1, HI_AE_LIB_NAME, sizeof(HI_AE_LIB_NAME));
180 CHECK_RET(HI_MPI_AE_UnRegister(IspDev, &stAeLib), "aelib unregister call back");
181 return HI_SUCCESS;
182 }
183
SAMPLE_COMM_ISP_Awblib_Callback(ISP_DEV IspDev)184 HI_S32 SAMPLE_COMM_ISP_Awblib_Callback(ISP_DEV IspDev)
185 {
186 ALG_LIB_S stAwbLib;
187
188 stAwbLib.s32Id = IspDev;
189 (HI_VOID)strncpy_s(stAwbLib.acLibName, sizeof(HI_AWB_LIB_NAME) + 1, HI_AWB_LIB_NAME, sizeof(HI_AWB_LIB_NAME));
190 CHECK_RET(HI_MPI_AWB_Register(IspDev, &stAwbLib), "awblib register call back");
191 return HI_SUCCESS;
192 }
193
SAMPLE_COMM_ISP_Awblib_UnCallback(ISP_DEV IspDev)194 HI_S32 SAMPLE_COMM_ISP_Awblib_UnCallback(ISP_DEV IspDev)
195 {
196 ALG_LIB_S stAwbLib;
197
198 stAwbLib.s32Id = IspDev;
199 (HI_VOID)strncpy_s(stAwbLib.acLibName, sizeof(HI_AWB_LIB_NAME) + 1, HI_AWB_LIB_NAME, sizeof(HI_AWB_LIB_NAME));
200 CHECK_RET(HI_MPI_AWB_UnRegister(IspDev, &stAwbLib), "awblib unregister call back");
201 return HI_SUCCESS;
202 }
203
SAMPLE_COMM_ISP_Run(ISP_DEV IspDev)204 HI_S32 SAMPLE_COMM_ISP_Run(ISP_DEV IspDev)
205 {
206 HI_S32 s32Ret = 0;
207 pthread_attr_t *pstAttr = NULL;
208
209 s32Ret = pthread_create(&g_IspPid[IspDev], pstAttr, SAMPLE_COMM_ISP_Thread, (HI_VOID *)(HI_UINTPTR_T)IspDev);
210 if (s32Ret != HI_SUCCESS) {
211 SAMPLE_PRT("create isp running thread failed!, error: %d\r\n", s32Ret);
212 }
213
214 if (pstAttr != NULL) {
215 pthread_attr_destroy(pstAttr);
216 }
217
218 return s32Ret;
219 }
220
SAMPLE_COMM_ISP_Sensor_Regiter_callback(ISP_DEV IspDev,HI_U32 u32SnsId)221 HI_S32 SAMPLE_COMM_ISP_Sensor_Regiter_callback(ISP_DEV IspDev, HI_U32 u32SnsId)
222 {
223 ALG_LIB_S stAeLib;
224 ALG_LIB_S stAwbLib;
225 const ISP_SNS_OBJ_S *pstSnsObj = HI_NULL;
226 HI_S32 s32Ret = HI_FAILURE;
227
228 if (u32SnsId >= MAX_SENSOR_NUM) {
229 SAMPLE_PRT("invalid sensor id: %d\n", u32SnsId);
230 return s32Ret;
231 }
232
233 pstSnsObj = SAMPLE_COMM_ISP_GetSnsObj(u32SnsId);
234 if (pstSnsObj == HI_NULL) {
235 SAMPLE_PRT("sensor %d not exist!\n", u32SnsId);
236 return s32Ret;
237 }
238
239 stAeLib.s32Id = IspDev;
240 stAwbLib.s32Id = IspDev;
241 (HI_VOID)strncpy_s(stAeLib.acLibName, sizeof(HI_AE_LIB_NAME) + 1, HI_AE_LIB_NAME, sizeof(HI_AE_LIB_NAME));
242 (HI_VOID)strncpy_s(stAwbLib.acLibName, sizeof(HI_AWB_LIB_NAME) + 1, HI_AWB_LIB_NAME, sizeof(HI_AWB_LIB_NAME));
243
244 if (pstSnsObj->pfnRegisterCallback != HI_NULL) {
245 s32Ret = pstSnsObj->pfnRegisterCallback(IspDev, &stAeLib, &stAwbLib);
246 if (s32Ret != HI_SUCCESS) {
247 SAMPLE_PRT("sensor_register_callback failed with %#x!\n", s32Ret);
248 return s32Ret;
249 }
250 } else {
251 SAMPLE_PRT("sensor_register_callback failed with HI_NULL!\n");
252 }
253
254 g_au32IspSnsId[IspDev] = u32SnsId;
255
256 return HI_SUCCESS;
257 }
258
SAMPLE_COMM_ISP_Sensor_UnRegiter_callback(ISP_DEV IspDev)259 HI_S32 SAMPLE_COMM_ISP_Sensor_UnRegiter_callback(ISP_DEV IspDev)
260 {
261 ALG_LIB_S stAeLib;
262 ALG_LIB_S stAwbLib;
263 HI_U32 u32SnsId;
264 const ISP_SNS_OBJ_S *pstSnsObj = HI_NULL;
265 HI_S32 s32Ret = HI_FAILURE;
266
267 u32SnsId = g_au32IspSnsId[IspDev];
268 if (u32SnsId >= MAX_SENSOR_NUM) {
269 SAMPLE_PRT("%s: invalid sensor id: %d\n", __FUNCTION__, u32SnsId);
270 return s32Ret;
271 }
272
273 pstSnsObj = SAMPLE_COMM_ISP_GetSnsObj(u32SnsId);
274 if (pstSnsObj == HI_NULL) {
275 return s32Ret;
276 }
277
278 stAeLib.s32Id = IspDev;
279 stAwbLib.s32Id = IspDev;
280 (HI_VOID)strncpy_s(stAeLib.acLibName, sizeof(HI_AE_LIB_NAME) + 1, HI_AE_LIB_NAME, sizeof(HI_AE_LIB_NAME));
281 (HI_VOID)strncpy_s(stAwbLib.acLibName, sizeof(HI_AWB_LIB_NAME) + 1, HI_AWB_LIB_NAME, sizeof(HI_AWB_LIB_NAME));
282 if (pstSnsObj->pfnUnRegisterCallback != HI_NULL) {
283 s32Ret = pstSnsObj->pfnUnRegisterCallback(IspDev, &stAeLib, &stAwbLib);
284 if (s32Ret != HI_SUCCESS) {
285 SAMPLE_PRT("sensor_unregister_callback failed with %#x!\n", s32Ret);
286 return s32Ret;
287 }
288 } else {
289 SAMPLE_PRT("sensor_unregister_callback failed with HI_NULL!\n");
290 }
291
292 return HI_SUCCESS;
293 }
294
295 /* function : stop ISP, and stop isp thread */
SAMPLE_COMM_ISP_Stop(ISP_DEV IspDev)296 HI_VOID SAMPLE_COMM_ISP_Stop(ISP_DEV IspDev)
297 {
298 if (g_IspPid[IspDev]) {
299 HI_MPI_ISP_Exit(IspDev);
300 pthread_join(g_IspPid[IspDev], NULL);
301 SAMPLE_COMM_ISP_Awblib_UnCallback(IspDev);
302 SAMPLE_COMM_ISP_Aelib_UnCallback(IspDev);
303 SAMPLE_COMM_ISP_Sensor_UnRegiter_callback(IspDev);
304 g_IspPid[IspDev] = 0;
305 }
306
307 return;
308 }
309
SAMPLE_COMM_All_ISP_Stop(HI_VOID)310 HI_VOID SAMPLE_COMM_All_ISP_Stop(HI_VOID)
311 {
312 ISP_DEV IspDev;
313
314 for (IspDev = 0; IspDev < ISP_MAX_PIPE_NUM; IspDev++) {
315 SAMPLE_COMM_ISP_Stop(IspDev);
316 }
317 }
318
SAMPLE_COMM_GetSnsBusType(SAMPLE_SNS_TYPE_E enSnsType)319 static ISP_SNS_TYPE_E SAMPLE_COMM_GetSnsBusType(SAMPLE_SNS_TYPE_E enSnsType)
320 {
321 return ISP_SNS_I2C_TYPE;
322 }
323
SAMPLE_COMM_ISP_BindSns(ISP_DEV IspDev,HI_U32 u32SnsId,SAMPLE_SNS_TYPE_E enSnsType,HI_S8 s8SnsDev)324 HI_S32 SAMPLE_COMM_ISP_BindSns(ISP_DEV IspDev, HI_U32 u32SnsId, SAMPLE_SNS_TYPE_E enSnsType, HI_S8 s8SnsDev)
325 {
326 ISP_SNS_COMMBUS_U uSnsBusInfo;
327 ISP_SNS_TYPE_E enBusType;
328 const ISP_SNS_OBJ_S *pstSnsObj = HI_NULL;
329 HI_S32 s32Ret;
330
331 if (u32SnsId >= MAX_SENSOR_NUM) {
332 SAMPLE_PRT("invalid sensor id: %d\n", u32SnsId);
333 return HI_FAILURE;
334 }
335
336 pstSnsObj = SAMPLE_COMM_ISP_GetSnsObj(u32SnsId);
337 if (pstSnsObj == HI_NULL) {
338 SAMPLE_PRT("sensor %d not exist!\n", u32SnsId);
339 return HI_FAILURE;
340 }
341
342 enBusType = SAMPLE_COMM_GetSnsBusType(enSnsType);
343 if (enBusType == ISP_SNS_I2C_TYPE) {
344 uSnsBusInfo.s8I2cDev = s8SnsDev;
345 } else {
346 uSnsBusInfo.s8SspDev.bit4SspDev = s8SnsDev;
347 uSnsBusInfo.s8SspDev.bit4SspCs = 0;
348 }
349
350 if (pstSnsObj->pfnSetBusInfo != HI_NULL) {
351 s32Ret = pstSnsObj->pfnSetBusInfo(IspDev, uSnsBusInfo);
352 if (s32Ret != HI_SUCCESS) {
353 SAMPLE_PRT("set sensor bus info failed with %#x!\n", s32Ret);
354 return s32Ret;
355 }
356 } else {
357 SAMPLE_PRT("not support set sensor bus info!\n");
358 return HI_FAILURE;
359 }
360
361 return s32Ret;
362 }
363
364 #ifdef __cplusplus
365 #if __cplusplus
366 }
367 #endif
368 #endif /* End of #ifdef __cplusplus */
369