1 /*
2 * Copyright (c) Texas Instruments Incorporated 2018
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the
14 * distribution.
15 *
16 * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
33 /**
34 * \file fvid2_drvMgr.c
35 *
36 * \brief FVID2 driver manager layer.
37 * This file implements driver management functionality.
38 *
39 */
41 /* ========================================================================== */
42 /* Include Files */
43 /* ========================================================================== */
45 #include <ti/drv/fvid2/include/fvid2_drvMgr.h>
47 /* ========================================================================== */
48 /* Macros & Typedefs */
49 /* ========================================================================== */
51 /** \brief Number of entries in FVID2 standard info table. */
52 #define FDM_NUM_STD_INFO_ENTRIES (sizeof (gFdmStdInfoTable) / \
53 sizeof (Fvid2_ModeInfo))
55 /** \brief Number of entries in FVID2 standard info table. */
56 #define FDM_NUM_DATA_FMT_STR_ENTRIES (sizeof (gFdmDataFmtStrTable) / \
57 sizeof (Fdm_DataFmtString))
59 /** \brief Number of entries in FVID2 standard info table. */
60 #define FDM_NUM_STD_STR_ENTRIES (sizeof (gFdmStdStrTable) / \
61 sizeof (Fdm_StdString))
63 /* ========================================================================== */
64 /* Structure Declarations */
65 /* ========================================================================== */
67 /**
68 * struct Fdm_Driver
69 * \brief Structure to store driver information.
70 */
71 typedef struct
72 {
73 const Fvid2_DrvOps *drvOps;
74 /**< Driver operation table pointer. */
75 uint32_t numOpens;
76 /**< Number of times the driver is opened using create API. */
77 uint32_t isUsed;
78 /**< Flag indicating whether the object is used or not. */
79 } Fdm_Driver;
81 /**
82 * struct Fdm_Channel
83 * \brief Structure to store channel information.
84 */
85 typedef struct
86 {
87 Fdm_Driver *drv;
88 /**< Pointer to the driver object to which this channel is created. */
89 Fdrv_Handle drvHandle;
90 /**< Driver handle returned by the actual driver. */
91 Fvid2_CbParams cbParams;
92 /**< Application call back parameters. */
93 uint32_t isUsed;
94 /**< Flag indicating whether the object is used or not. */
95 } Fdm_Channel;
97 /**
98 * struct Fdm_DataFmtString
99 * \brief Structure to store data format and string pair.
100 */
101 typedef struct
102 {
103 Fvid2_DataFormat dataFmt;
104 /**< Data format. */
105 const char *dataFmtStr;
106 /**< Pointer to data format string. */
107 } Fdm_DataFmtString;
109 /**
110 * struct Fdm_StdString
111 * \brief Structure to store standard and string pair.
112 */
113 typedef struct
114 {
115 Fvid2_Standard standard;
116 /**< Standard. */
117 const char *stdStr;
118 /**< Pointer to data format string. */
119 } Fdm_StdString;
121 /**
122 * struct Fdm_Object
123 * \brief Struture to store all global objects.
124 */
125 typedef struct
126 {
127 char *versionString;
128 /**< FVID2 drivers version number as string. */
129 uint32_t versionNumber;
130 /**< FVID2 drivers version number as string. */
131 Fdm_Driver fdmDriverObjects[FVID2_CFG_FDM_NUM_DRV_OBJS];
132 /**< FDM Driver objects. */
133 Fdm_Channel fdmChannelObjects[FVID2_CFG_FDM_NUM_CH_OBJS];
134 /**< FDM Channel objects. */
135 SemaphoreP_Handle lockSem;
136 /**< Semaphore to protect function calls and other memory allocation. */
137 } Fdm_Object;
139 /* ========================================================================== */
140 /* Function Declarations */
141 /* ========================================================================== */
142 /**
143 * Below ifdef __cplusplus is added so that C++ build passes without
144 * typecasting. This is because the prototype is build as C type
145 * whereas this file is build as CPP file. Hence we get C++ build error.
146 * Also if tyecasting is used, then we get MisraC error Rule 11.1.
147 */
148 #ifdef __cplusplus
149 extern "C" {
150 #endif
151 static int32_t fdmDriverCbFxn(void *fdmData);
152 static int32_t fdmDriverErrCbFxn(void *fdmData, void *errList);
153 static Fdm_Driver *fdmAllocDriverObject(void);
154 static int32_t fdmFreeDriverObject(const Fvid2_DrvOps *drvOps);
155 static Fdm_Channel *fdmAllocChannelObject(void);
156 static int32_t fdmFreeChannelObject(Fdm_Channel *channel);
157 #ifdef __cplusplus
158 }
159 #endif
161 /* ========================================================================== */
162 /* Global Variables */
163 /* ========================================================================== */
165 /** \brief FDM objects. */
166 static Fdm_Object gFdmObj;
168 /** \brief FVID2 standard information table. */
169 static Fvid2_ModeInfo gFdmStdInfoTable[] =
170 {
171 /* Standard, FrameWidth, FrameHeight, ScanFormat, PixelClock (KHz), FPS */
172 {FVID2_STD_NTSC, 720U, 480U, FVID2_SF_INTERLACED, 27000U, 30U,
173 0U, 0U, 0U, 0U, 0U, 0U},
174 {FVID2_STD_PAL, 720U, 576U, FVID2_SF_INTERLACED, 27000U, 25U,
175 0U, 0U, 0U, 0U, 0U, 0U},
176 {FVID2_STD_480I, 720U, 480U, FVID2_SF_INTERLACED, 27000U, 30U,
177 0U, 0U, 0U, 0U, 0U, 0U},
178 {FVID2_STD_576I, 720U, 576U, FVID2_SF_INTERLACED, 27000U, 25U,
179 0U, 0U, 0U, 0U, 0U, 0U},
180 {FVID2_STD_480P, 720U, 480U, FVID2_SF_PROGRESSIVE,27000U, 60U,
181 0U, 0U, 0U, 0U, 0U, 0U},
182 {FVID2_STD_576P, 720U, 576U, FVID2_SF_PROGRESSIVE,27000U, 50U,
183 0U, 0U, 0U, 0U, 0U, 0U},
184 {FVID2_STD_720P_60, 1280U, 720U, FVID2_SF_PROGRESSIVE,74250U, 60U,
185 0U, 0U, 0U, 0U, 0U, 0U},
186 {FVID2_STD_720P_50, 1280U, 720U, FVID2_SF_PROGRESSIVE,74250U, 50U,
187 0U, 0U, 0U, 0U, 0U, 0U},
188 {FVID2_STD_1080I_60, 1920U, 1080U, FVID2_SF_INTERLACED, 74250U, 30U,
189 0U, 0U, 0U, 0U, 0U, 0U},
190 {FVID2_STD_1080I_50, 1920U, 1080U, FVID2_SF_INTERLACED, 74250U, 25U,
191 0U, 0U, 0U, 0U, 0U, 0U},
192 {FVID2_STD_1080P_60, 1920U, 1080U, FVID2_SF_PROGRESSIVE,148500U, 60U,
193 0U, 0U, 0U, 0U, 0U, 0U},
194 {FVID2_STD_1080P_50, 1920U, 1080U, FVID2_SF_PROGRESSIVE,148500U, 50U,
195 0U, 0U, 0U, 0U, 0U, 0U},
196 {FVID2_STD_1080P_24, 1920U, 1080U, FVID2_SF_PROGRESSIVE,74250U, 24U,
197 0U, 0U, 0U, 0U, 0U, 0U},
198 {FVID2_STD_1080P_30, 1920U, 1080U, FVID2_SF_PROGRESSIVE,74250U, 30U,
199 0U, 0U, 0U, 0U, 0U, 0U},
200 {FVID2_STD_VGA_60, 640U, 480U, FVID2_SF_PROGRESSIVE,25175U, 60U,
201 0U, 0U, 0U, 0U, 0U, 0U},
202 {FVID2_STD_VGA_72, 640U, 480U, FVID2_SF_PROGRESSIVE,31500U, 72U,
203 0U, 0U, 0U, 0U, 0U, 0U},
204 {FVID2_STD_VGA_75, 640U, 480U, FVID2_SF_PROGRESSIVE,31500U, 75U,
205 0U, 0U, 0U, 0U, 0U, 0U},
206 {FVID2_STD_VGA_85, 640U, 480U, FVID2_SF_PROGRESSIVE,36000U, 85U,
207 0U, 0U, 0U, 0U, 0U, 0U},
208 {FVID2_STD_WVGA_60, 800U, 480U, FVID2_SF_PROGRESSIVE,33500U, 60U,
209 0U, 0U, 0U, 0U, 0U, 0U},
210 {FVID2_STD_SVGA_60, 800U, 600U, FVID2_SF_PROGRESSIVE,40000U, 60U,
211 0U, 0U, 0U, 0U, 0U, 0U},
212 {FVID2_STD_SVGA_72, 800U, 600U, FVID2_SF_PROGRESSIVE,50000U, 72U,
213 0U, 0U, 0U, 0U, 0U, 0U},
214 {FVID2_STD_SVGA_75, 800U, 600U, FVID2_SF_PROGRESSIVE,49500U, 75U,
215 0U, 0U, 0U, 0U, 0U, 0U},
216 {FVID2_STD_SVGA_85, 800U, 600U, FVID2_SF_PROGRESSIVE,56250U, 85U,
217 0U, 0U, 0U, 0U, 0U, 0U},
218 {FVID2_STD_WSVGA_70, 1024U, 600U, FVID2_SF_PROGRESSIVE,50800U, 70U,
219 0U, 0U, 0U, 0U, 0U, 0U},
220 {FVID2_STD_XGA_60, 1024U, 768U, FVID2_SF_PROGRESSIVE,65000U, 60U,
221 0U, 0U, 0U, 0U, 0U, 0U},
222 {FVID2_STD_XGA_DSS_TDM_60, 1024U, 768U, FVID2_SF_PROGRESSIVE,64000U, 60U,
223 0U, 0U, 0U, 0U, 0U, 0U},
224 {FVID2_STD_XGA_70, 1024U, 768U, FVID2_SF_PROGRESSIVE,75000U, 70U,
225 0U, 0U, 0U, 0U, 0U, 0U},
226 {FVID2_STD_XGA_75, 1024U, 768U, FVID2_SF_PROGRESSIVE,78750U, 75U,
227 0U, 0U, 0U, 0U, 0U, 0U},
228 {FVID2_STD_XGA_85, 1024U, 768U, FVID2_SF_PROGRESSIVE,94500U, 85U,
229 0U, 0U, 0U, 0U, 0U, 0U},
230 {FVID2_STD_WXGA_30, 1280U, 800U, FVID2_SF_PROGRESSIVE,34125U, 30U,
231 0U, 0U, 0U, 0U, 0U, 0U},
232 {FVID2_STD_WXGA_60, 1280U, 800U, FVID2_SF_PROGRESSIVE,83500U, 60U,
233 0U, 0U, 0U, 0U, 0U, 0U},
234 {FVID2_STD_WXGA_75, 1280U, 800U, FVID2_SF_PROGRESSIVE,102250U, 75U,
235 0U, 0U, 0U, 0U, 0U, 0U},
236 {FVID2_STD_WXGA_85, 1280U, 800U, FVID2_SF_PROGRESSIVE,117500U, 85U,
237 0U, 0U, 0U, 0U, 0U, 0U},
238 {FVID2_STD_1440_900_60, 1440U, 900U, FVID2_SF_PROGRESSIVE,106500U, 60U,
239 0U, 0U, 0U, 0U, 0U, 0U},
240 {FVID2_STD_1368_768_60, 1368U, 768U, FVID2_SF_PROGRESSIVE,85860U, 60U,
241 0U, 0U, 0U, 0U, 0U, 0U},
242 {FVID2_STD_1366_768_60, 1366U, 768U, FVID2_SF_PROGRESSIVE,85500U, 60U,
243 0U, 0U, 0U, 0U, 0U, 0U},
244 {FVID2_STD_1360_768_60, 1360U, 768U, FVID2_SF_PROGRESSIVE,85500U, 60U,
245 0U, 0U, 0U, 0U, 0U, 0U},
246 {FVID2_STD_SXGA_60, 1280U, 1024U, FVID2_SF_PROGRESSIVE,108000U, 60U,
247 0U, 0U, 0U, 0U, 0U, 0U},
248 {FVID2_STD_SXGA_75, 1280U, 1024U, FVID2_SF_PROGRESSIVE,135000U, 75U,
249 0U, 0U, 0U, 0U, 0U, 0U},
250 {FVID2_STD_SXGA_85, 1280U, 1024U, FVID2_SF_PROGRESSIVE,157500U, 85U,
251 0U, 0U, 0U, 0U, 0U, 0U},
252 {FVID2_STD_WSXGAP_60, 1680U, 1050U, FVID2_SF_PROGRESSIVE,146250U, 60U,
253 0U, 0U, 0U, 0U, 0U, 0U},
254 {FVID2_STD_SXGAP_60, 1400U, 1050U, FVID2_SF_PROGRESSIVE,121750U, 60U,
255 0U, 0U, 0U, 0U, 0U, 0U},
256 {FVID2_STD_SXGAP_75, 1400U, 1050U, FVID2_SF_PROGRESSIVE,156000U, 75U,
257 0U, 0U, 0U, 0U, 0U, 0U},
258 {FVID2_STD_UXGA_60, 1600U, 1200U, FVID2_SF_PROGRESSIVE,162000U, 60U,
259 0U, 0U, 0U, 0U, 0U, 0U},
260 {FVID2_STD_WXGA_5x3_30, 1280U, 800U, FVID2_SF_PROGRESSIVE,34125U, 30U,
261 0U, 0U, 0U, 0U, 0U, 0U},
262 {FVID2_STD_WXGA_5x3_60, 1280U, 800U, FVID2_SF_PROGRESSIVE,68250U, 60U,
263 0U, 0U, 0U, 0U, 0U, 0U},
264 {FVID2_STD_WXGA_5x3_75, 1280U, 800U, FVID2_SF_PROGRESSIVE,102250U, 75U,
265 0U, 0U, 0U, 0U, 0U, 0U}
266 };
268 /** \brief Data format string table. */
269 static Fdm_DataFmtString gFdmDataFmtStrTable[] =
270 {
271 {FVID2_DF_YUV422I_UYVY, "YUV422I_UYVY" },
272 {FVID2_DF_YUV422I_YUYV, "YUV422I_YUYV" },
273 {FVID2_DF_YUV422I_YVYU, "YUV422I_YVYU" },
274 {FVID2_DF_YUV422I_VYUY, "YUV422I_VYUY" },
275 {FVID2_DF_YUV422SP_UV, "YUV422SP_UV" },
276 {FVID2_DF_YUV422SP_VU, "YUV422SP_VU" },
277 {FVID2_DF_YUV422P, "YUV422P" },
278 {FVID2_DF_YUV420SP_UV, "YUV420SP_UV" },
279 {FVID2_DF_YUV420SP_VU, "YUV420SP_VU" },
280 {FVID2_DF_YUV420P, "YUV420P" },
281 {FVID2_DF_YUV444P, "YUV444P" },
282 {FVID2_DF_YUV444I, "YUV444I" },
283 {FVID2_DF_RGB16_565, "RGB16_565" },
284 {FVID2_DF_ARGB16_1555, "ARGB16_1555" },
285 {FVID2_DF_RGBA16_5551, "RGBA16_5551" },
286 {FVID2_DF_ARGB16_4444, "ARGB16_4444" },
287 {FVID2_DF_RGBA16_4444, "RGBA16_4444" },
288 {FVID2_DF_BGRX_4444, "RGBX12_4444" },
289 {FVID2_DF_XBGR_4444, "XRGB12_4444" },
290 {FVID2_DF_ARGB24_6666, "ARGB24_6666" },
291 {FVID2_DF_RGBA24_6666, "RGBA24_6666" },
292 {FVID2_DF_RGB24_888, "RGB24_888" },
293 {FVID2_DF_XBGR24_8888, "XBGR24_8888" },
294 {FVID2_DF_RGBX24_8888, "RGBX24_8888" },
295 {FVID2_DF_BGRX24_8888, "BGRX24_8888" },
296 {FVID2_DF_ARGB32_8888, "ARGB32_8888" },
297 {FVID2_DF_RGBA32_8888, "RGBA32_8888" },
298 {FVID2_DF_BGR16_565, "BGR16_565" },
299 {FVID2_DF_ABGR16_1555, "ABGR16_1555" },
300 {FVID2_DF_ABGR16_4444, "ABGR16_4444" },
301 {FVID2_DF_BGRA16_5551, "BGRA16_5551" },
302 {FVID2_DF_BGRA16_4444, "BGRA16_4444" },
303 {FVID2_DF_AGBR16_1555, "AGBR16_1555" },
304 {FVID2_DF_AGBR16_4444, "AGBR16_4444" },
305 {FVID2_DF_XGBR16_1555, "XGBR16_1555" },
306 {FVID2_DF_BGRX16_5551, "BGRX16_5551" },
307 {FVID2_DF_ABGR24_6666, "ABGR24_6666" },
308 {FVID2_DF_BGR24_888, "BGR24_888" },
309 {FVID2_DF_ABGR32_8888, "ABGR32_8888" },
310 {FVID2_DF_BGRA24_6666, "BGRA24_6666" },
311 {FVID2_DF_BGRA32_8888, "BGRA32_8888" },
312 {FVID2_DF_BITMAP8, "BITMAP8" },
313 {FVID2_DF_BITMAP4_LOWER, "BITMAP4_LOWER" },
314 {FVID2_DF_BITMAP4_UPPER, "BITMAP4_UPPER" },
315 {FVID2_DF_BITMAP2_OFFSET0, "BITMAP2_OFFSET0" },
316 {FVID2_DF_BITMAP2_OFFSET1, "BITMAP2_OFFSET1" },
317 {FVID2_DF_BITMAP2_OFFSET2, "BITMAP2_OFFSET2" },
318 {FVID2_DF_BITMAP2_OFFSET3, "BITMAP2_OFFSET3" },
319 {FVID2_DF_BITMAP1_OFFSET0, "BITMAP1_OFFSET0" },
320 {FVID2_DF_BITMAP1_OFFSET1, "BITMAP1_OFFSET1" },
321 {FVID2_DF_BITMAP1_OFFSET2, "BITMAP1_OFFSET2" },
322 {FVID2_DF_BITMAP1_OFFSET3, "BITMAP1_OFFSET3" },
323 {FVID2_DF_BITMAP1_OFFSET4, "BITMAP1_OFFSET4" },
324 {FVID2_DF_BITMAP1_OFFSET5, "BITMAP1_OFFSET5" },
325 {FVID2_DF_BITMAP1_OFFSET6, "BITMAP1_OFFSET6" },
326 {FVID2_DF_BITMAP1_OFFSET7, "BITMAP1_OFFSET7" },
327 {FVID2_DF_BITMAP8_BGRA32, "BITMAP8_BGRA32" },
328 {FVID2_DF_BITMAP4_BGRA32_LOWER, "BITMAP4_BGRA32_LOWER" },
329 {FVID2_DF_BITMAP4_BGRA32_UPPER, "BITMAP4_BGRA32_UPPER" },
330 {FVID2_DF_BITMAP2_BGRA32_OFFSET0, "BITMAP2_BGRA32_OFFSET0"},
331 {FVID2_DF_BITMAP2_BGRA32_OFFSET1, "BITMAP2_BGRA32_OFFSET1"},
332 {FVID2_DF_BITMAP2_BGRA32_OFFSET2, "BITMAP2_BGRA32_OFFSET2"},
333 {FVID2_DF_BITMAP2_BGRA32_OFFSET3, "BITMAP2_BGRA32_OFFSET3"},
334 {FVID2_DF_BITMAP1_BGRA32_OFFSET0, "BITMAP1_BGRA32_OFFSET0"},
335 {FVID2_DF_BITMAP1_BGRA32_OFFSET1, "BITMAP1_BGRA32_OFFSET1"},
336 {FVID2_DF_BITMAP1_BGRA32_OFFSET2, "BITMAP1_BGRA32_OFFSET2"},
337 {FVID2_DF_BITMAP1_BGRA32_OFFSET3, "BITMAP1_BGRA32_OFFSET3"},
338 {FVID2_DF_BITMAP1_BGRA32_OFFSET4, "BITMAP1_BGRA32_OFFSET4"},
339 {FVID2_DF_BITMAP1_BGRA32_OFFSET5, "BITMAP1_BGRA32_OFFSET5"},
340 {FVID2_DF_BITMAP1_BGRA32_OFFSET6, "BITMAP1_BGRA32_OFFSET6"},
341 {FVID2_DF_BITMAP1_BGRA32_OFFSET7, "BITMAP1_BGRA32_OFFSET7"},
342 {FVID2_DF_BAYER_RAW, "BAYER_RAW" },
343 {FVID2_DF_BAYER_GRBG, "BAYER_GRBG" },
344 {FVID2_DF_BAYER_RGGB, "BAYER_RGGB" },
345 {FVID2_DF_BAYER_BGGR, "BAYER_BGGR" },
346 {FVID2_DF_BAYER_GBRG, "BAYER_GBRG" },
347 {FVID2_DF_RAW_VBI, "RAW_VBI" },
348 {FVID2_DF_RAW24, "RAW24" },
349 {FVID2_DF_RAW16, "RAW16" },
350 {FVID2_DF_RAW08, "RAW08" },
351 {FVID2_DF_BGRX32_8888, "BGRX32_8888" },
352 {FVID2_DF_BGRA16_1555, "BGRA16_1555" },
353 {FVID2_DF_BGRX16_1555, "BGRX16_1555" },
354 {FVID2_DF_BGRA32_1010102, "BGRA32_1010102" },
355 {FVID2_DF_BGRX32_1010102, "BGRX32_1010102" },
356 {FVID2_DF_RGBA32_1010102, "RGBA32_1010102" },
357 {FVID2_DF_RGBX32_1010102, "RGBX32_1010102" },
358 {FVID2_DF_BGRA64_16161616, "BGRA64_16161616" },
359 {FVID2_DF_BGRX64_16161616, "BGRX64_16161616" },
360 {FVID2_DF_ABGR64_16161616, "ABGR64_16161616" },
361 {FVID2_DF_XBGR64_16161616, "XBGR64_16161616" },
362 {FVID2_DF_XRGB32_8888, "XRGB32_8888" },
363 {FVID2_DF_RGBX16_4444, "RGBX16_4444" },
364 {FVID2_DF_BGR16_565_A8, "BRG16_565_A8" },
365 {FVID2_DF_RGB16_565_A8, "RGB16_565_A8" },
366 {FVID2_DF_MISC, "MISC" },
367 {FVID2_DF_INVALID, "INVALID" },
368 };
370 /** \brief Standard string table. */
371 static Fdm_StdString gFdmStdStrTable[] =
372 {
373 {FVID2_STD_NTSC, "NTSC" },
374 {FVID2_STD_PAL, "PAL" },
375 {FVID2_STD_480I, "480I" },
376 {FVID2_STD_576I, "576I" },
377 {FVID2_STD_CIF, "CIF" },
378 {FVID2_STD_HALF_D1, "HALF_D1" },
379 {FVID2_STD_D1, "D1" },
380 {FVID2_STD_480P, "480P" },
381 {FVID2_STD_576P, "576P" },
382 {FVID2_STD_720P_60, "720P60" },
383 {FVID2_STD_720P_50, "720P50" },
384 {FVID2_STD_1080I_60, "1080I60" },
385 {FVID2_STD_1080I_50, "1080I50" },
386 {FVID2_STD_1080P_60, "1080P60" },
387 {FVID2_STD_1080P_50, "1080P50" },
388 {FVID2_STD_1080P_24, "1080P24" },
389 {FVID2_STD_1080P_30, "1080P30" },
390 {FVID2_STD_VGA_60, "VGA60" },
391 {FVID2_STD_VGA_72, "VGA72" },
392 {FVID2_STD_VGA_75, "VGA75" },
393 {FVID2_STD_VGA_85, "VGA85" },
394 {FVID2_STD_WVGA_60, "WVGA60" },
395 {FVID2_STD_SVGA_60, "SVGA60" },
396 {FVID2_STD_SVGA_72, "SVGA72" },
397 {FVID2_STD_SVGA_75, "SVGA75" },
398 {FVID2_STD_SVGA_85, "SVGA85" },
399 {FVID2_STD_WSVGA_70, "WSVGA70" },
400 {FVID2_STD_XGA_60, "XGA60" },
401 {FVID2_STD_XGA_DSS_TDM_60, "XGA_DSS_TDM_60" },
402 {FVID2_STD_XGA_70, "XGA70" },
403 {FVID2_STD_XGA_75, "XGA75" },
404 {FVID2_STD_XGA_85, "XGA85" },
405 {FVID2_STD_WXGA_30, "WXGA30" },
406 {FVID2_STD_WXGA_60, "WXGA60" },
407 {FVID2_STD_WXGA_75, "WXGA75" },
408 {FVID2_STD_WXGA_85, "WXGA85" },
409 {FVID2_STD_1440_900_60, "1440X900@60" },
410 {FVID2_STD_1368_768_60, "1368X768@60" },
411 {FVID2_STD_1366_768_60, "1366X768@60" },
412 {FVID2_STD_1360_768_60, "1360X768@60" },
413 {FVID2_STD_SXGA_60, "SXGA60" },
414 {FVID2_STD_SXGA_75, "SXGA75" },
415 {FVID2_STD_SXGA_85, "SXGA85" },
416 {FVID2_STD_WSXGAP_60, "WSXGAP60" },
417 {FVID2_STD_SXGAP_60, "SXGAP60" },
418 {FVID2_STD_SXGAP_75, "SXGAP75" },
419 {FVID2_STD_UXGA_60, "UXGA60" },
420 {FVID2_STD_MUX_2CH_D1, "MUX_2CH_D1" },
421 {FVID2_STD_MUX_2CH_HALF_D1, "MUX_2CH_HALF_D1"},
422 {FVID2_STD_MUX_2CH_CIF, "MUX_2CH_CIF" },
423 {FVID2_STD_MUX_4CH_D1, "MUX_4CH_D1" },
424 {FVID2_STD_MUX_4CH_CIF, "MUX_4CH_CIF" },
425 {FVID2_STD_MUX_4CH_HALF_D1, "MUX_4CH_HALF_D1"},
426 {FVID2_STD_MUX_8CH_CIF, "MUX_8CH_CIF" },
427 {FVID2_STD_MUX_8CH_HALF_D1, "MUX_8CH_HALF_D1"},
428 {FVID2_STD_WXGA_5x3_30, "WXGA_5x3_30" },
429 {FVID2_STD_WXGA_5x3_60, "WXGA_5x3_60" },
430 {FVID2_STD_WXGA_5x3_75, "WXGA_5x3_75" },
431 {FVID2_STD_AUTO_DETECT, "AUTO_DETECT" },
432 {FVID2_STD_CUSTOM, "CUSTOM" },
433 };
435 /* ========================================================================== */
436 /* Function Definitions */
437 /* ========================================================================== */
439 /**
440 * Fvid2_init
441 * \brief FVID2 init function.
442 *
443 * Initializes the drivers and the hardware.
444 * This function should be called before calling any of driver API's.
445 *
446 * \param arg Not used currently. Meant for future purpose.
447 *
448 * \return Returns 0 on success else returns error value.
449 */
450 int32_t Fvid2_init(void *args)
451 {
452 uint32_t cnt;
453 int32_t retVal = FVID2_SOK;
454 int32_t initValue;
455 SemaphoreP_Params params;
457 /* Init all global variables to zero */
458 Fvid2Utils_memset(&gFdmObj, 0U, sizeof (gFdmObj));
460 /* Mark pool flags as free */
461 for (cnt = 0u; cnt < FVID2_CFG_FDM_NUM_DRV_OBJS; cnt++)
462 {
463 gFdmObj.fdmDriverObjects[cnt].isUsed = (uint32_t) FALSE;
464 }
465 for (cnt = 0u; cnt < FVID2_CFG_FDM_NUM_CH_OBJS; cnt++)
466 {
467 gFdmObj.fdmChannelObjects[cnt].isUsed = (uint32_t) FALSE;
468 }
470 gFdmObj.versionString = FVID2_VERSION_STRING;
471 gFdmObj.versionNumber = FVID2_VERSION_NUMBER;
473 /* Allocate lock semaphore */
474 SemaphoreP_Params_init(¶ms);
475 params.mode = SemaphoreP_Mode_BINARY;
476 initValue = 1;
477 gFdmObj.lockSem = SemaphoreP_create(initValue, ¶ms);
478 if (NULL == gFdmObj.lockSem)
479 {
480 Fvid2_printf("FVID2 semaphore create failed!!\r\n");
481 retVal = FVID2_EALLOC;
482 }
484 /* Free-up memory if error occurs */
485 if (FVID2_SOK != retVal)
486 {
487 Fvid2_deInit(NULL);
488 }
490 return (retVal);
491 }
493 /**
494 * Fvid2_deInit
495 * \brief FVID2 deinit function.
496 *
497 * Uninitializes the drivers and the hardware.
498 *
499 * \param arg Not used currently. Meant for future purpose.
500 *
501 * \return Returns 0 on success else returns error value.
502 */
503 int32_t Fvid2_deInit(void *args)
504 {
505 int32_t retVal = FVID2_SOK;
507 /* Delete the lock semaphore */
508 if (NULL != gFdmObj.lockSem)
509 {
510 SemaphoreP_delete(gFdmObj.lockSem);
511 gFdmObj.lockSem = NULL;
512 }
514 return (retVal);
515 }
517 /**
518 * Fvid2_getVersionString
519 * \brief Get the FVID2 driver version in string form. This API can be
520 * called before calling #Fvid2_init().
521 *
522 * \return Returns pointer to FVID2 version string.
523 */
524 const char *Fvid2_getVersionString(void)
525 {
526 return (FVID2_VERSION_STRING);
527 }
529 /**
530 * Fvid2_getVersionNumber
531 * \brief Get the FVID2 driver version in number form. This API can be
532 * called before calling #Fvid2_init().
533 *
534 * \return FVID2 version number.
535 */
536 uint32_t Fvid2_getVersionNumber(void)
537 {
538 return (FVID2_VERSION_NUMBER);
539 }
541 /**
542 * Fvid2_registerDriver
543 * \brief FVID2 register driver function.
544 */
545 int32_t Fvid2_registerDriver(const Fvid2_DrvOps *drvOps)
546 {
547 int32_t retVal = FVID2_SOK;
548 Fdm_Driver *drv;
549 uint32_t cnt;
551 /* Check for NULL pointers */
552 OSAL_Assert(NULL == drvOps);
554 SemaphoreP_pend(gFdmObj.lockSem, SemaphoreP_WAIT_FOREVER);
556 /* Check whether the driver is already registered */
557 for (cnt = 0u; cnt < FVID2_CFG_FDM_NUM_DRV_OBJS; cnt++)
558 {
559 if (TRUE == gFdmObj.fdmDriverObjects[cnt].isUsed)
560 {
561 /* Check for NULL pointers */
562 OSAL_Assert(NULL == gFdmObj.fdmDriverObjects[cnt].drvOps);
564 if (drvOps->drvId == gFdmObj.fdmDriverObjects[cnt].drvOps->drvId)
565 {
566 Fvid2_printf("Driver with same id already registered!!\r\n");
567 retVal = FVID2_EDRIVER_INUSE;
568 break;
569 }
570 }
571 }
573 if (FVID2_SOK == retVal)
574 {
575 /* Get a free driver object */
576 drv = fdmAllocDriverObject();
577 if (NULL != drv)
578 {
579 drv->drvOps = drvOps;
580 drv->numOpens = 0U;
581 }
582 else
583 {
584 Fvid2_printf("Alloc driver object failed!!\r\n");
585 retVal = FVID2_EALLOC;
586 }
587 }
589 SemaphoreP_post(gFdmObj.lockSem);
591 return (retVal);
592 }
594 /**
595 * Fvid2_unRegisterDriver
596 * \brief FVID2 unregister driver function.
597 */
598 int32_t Fvid2_unRegisterDriver(const Fvid2_DrvOps *drvOps)
599 {
600 int32_t retVal = FVID2_EFAIL;
602 /* Check for NULL pointers */
603 OSAL_Assert(NULL == drvOps);
605 SemaphoreP_pend(gFdmObj.lockSem, SemaphoreP_WAIT_FOREVER);
607 /* Free the driver object */
608 retVal = fdmFreeDriverObject(drvOps);
610 SemaphoreP_post(gFdmObj.lockSem);
612 return (retVal);
613 }
615 /**
616 * Fvid2_create
617 * \brief Opens the driver identified by the driver ID.
618 */
619 Fvid2_Handle Fvid2_create(uint32_t drvId,
620 uint32_t instanceId,
621 void *createArgs,
622 void *createStatusArgs,
623 const Fvid2_CbParams *cbParams)
624 {
625 Fdm_Driver *drv = NULL;
626 uint32_t cnt;
627 Fdrv_Handle drvHandle = NULL;
628 Fdm_Channel *channel = NULL;
629 Fvid2_DrvCbParams fdmCbParams, *tempCbParams;
631 SemaphoreP_pend(gFdmObj.lockSem, SemaphoreP_WAIT_FOREVER);
633 /* Get the matching driver object */
634 for (cnt = 0u; cnt < FVID2_CFG_FDM_NUM_DRV_OBJS; cnt++)
635 {
636 if (TRUE == gFdmObj.fdmDriverObjects[cnt].isUsed)
637 {
638 /* Check for NULL pointers */
639 OSAL_Assert(NULL == gFdmObj.fdmDriverObjects[cnt].drvOps);
641 if (drvId == gFdmObj.fdmDriverObjects[cnt].drvOps->drvId)
642 {
643 drv = &gFdmObj.fdmDriverObjects[cnt];
644 /* Allocate channel object */
645 channel = fdmAllocChannelObject();
646 break;
647 }
648 }
649 }
651 if (NULL != channel)
652 {
653 if (NULL != drv->drvOps->createFxn)
654 {
655 if (NULL != cbParams)
656 {
657 if (NULL != cbParams->cbFxn)
658 {
659 fdmCbParams.fdmCbFxn = &fdmDriverCbFxn;
660 }
661 else
662 {
663 fdmCbParams.fdmCbFxn = NULL;
664 }
665 if (NULL != cbParams->errCbFxn)
666 {
667 fdmCbParams.fdmErrCbFxn = &fdmDriverErrCbFxn;
668 }
669 else
670 {
671 fdmCbParams.fdmErrCbFxn = NULL;
672 }
674 fdmCbParams.handle = channel;
675 fdmCbParams.errList = cbParams->errList;
676 fdmCbParams.fdmData = channel;
677 tempCbParams = &fdmCbParams;
678 }
679 else
680 {
681 tempCbParams = NULL;
682 }
684 /* Call the driver's create function */
685 drvHandle = drv->drvOps->createFxn(
686 drvId,
687 instanceId,
688 createArgs,
689 createStatusArgs,
690 tempCbParams);
691 }
692 else
693 {
694 Fvid2_printf("Driver Ops not supported!!\r\n");
695 }
697 if (NULL != drvHandle)
698 {
699 drv->numOpens++;
701 channel->drv = drv;
702 channel->drvHandle = drvHandle;
703 Fvid2CbParams_init(&channel->cbParams);
704 if (NULL != cbParams)
705 {
706 Fvid2Utils_memcpy(
707 &channel->cbParams,
708 cbParams,
709 sizeof (Fvid2_CbParams));
710 }
711 }
712 else
713 {
714 Fvid2_printf("Driver create failed!!\r\n");
716 /* Free the allocated channel object */
717 fdmFreeChannelObject(channel);
718 channel = NULL;
719 }
720 }
721 else
722 {
723 Fvid2_printf("EALLOC: Invalid driver ID!!\r\n");
724 }
726 SemaphoreP_post(gFdmObj.lockSem);
728 return (channel);
729 }
731 /**
732 * Fvid2_delete
733 * \brief Application calls Fvid2_delete to close the logical channel
734 * associated with FVID2 handle.
735 */
736 int32_t Fvid2_delete(Fvid2_Handle handle, void *deleteArgs)
737 {
738 int32_t retVal = FVID2_SOK;
739 Fdm_Channel *channel;
741 SemaphoreP_pend(gFdmObj.lockSem, SemaphoreP_WAIT_FOREVER);
743 if (NULL != handle)
744 {
745 channel = (Fdm_Channel *) handle;
747 /* Check for NULL pointers */
748 OSAL_Assert(NULL == channel->drv);
749 OSAL_Assert(NULL == channel->drv->drvOps);
751 if (NULL != channel->drv->drvOps->deleteFxn)
752 {
753 /* Call the driver's delete function */
754 retVal = channel->drv->drvOps->deleteFxn(
755 channel->drvHandle,
756 deleteArgs);
757 }
758 else
759 {
760 Fvid2_printf("Driver Ops not supported!!\r\n");
761 }
763 channel->drv->numOpens--;
764 /* Free the allocated channel object */
765 channel->drv = NULL;
766 channel->drvHandle = NULL;
767 channel->cbParams.cbFxn = NULL;
768 channel->cbParams.errCbFxn = NULL;
769 channel->cbParams.errList = NULL;
770 channel->cbParams.appData = NULL;
771 fdmFreeChannelObject(channel);
772 }
773 else
774 {
775 Fvid2_printf("EBADARGS: NULL pointer!!\r\n");
776 retVal = FVID2_EBADARGS;
777 }
779 SemaphoreP_post(gFdmObj.lockSem);
781 return (retVal);
782 }
784 /**
785 * Fvid2_control
786 * \brief An application calls Fvid2_control to send device-specific control
787 * commands to the video driver.
788 */
789 int32_t Fvid2_control(Fvid2_Handle handle,
790 uint32_t cmd,
791 void *cmdArgs,
792 void *cmdStatusArgs)
793 {
794 int32_t retVal = FVID2_SOK;
795 Fdm_Channel *channel;
797 if (NULL != handle)
798 {
799 channel = (Fdm_Channel *) handle;
801 /* Check for NULL pointers */
802 OSAL_Assert(NULL == channel->drv);
803 OSAL_Assert(NULL == channel->drv->drvOps);
805 if (NULL != channel->drv->drvOps->controlFxn)
806 {
807 /* Call the driver's control function */
808 retVal = channel->drv->drvOps->controlFxn(
809 channel->drvHandle,
810 cmd,
811 cmdArgs,
812 cmdStatusArgs);
813 }
814 else
815 {
816 Fvid2_printf("Driver Ops not supported!!\r\n");
817 retVal = FVID2_EUNSUPPORTED_OPS;
818 }
819 }
820 else
821 {
822 Fvid2_printf("EBADARGS: NULL pointer!!\r\n");
823 retVal = FVID2_EBADARGS;
824 }
826 return (retVal);
827 }
829 /**
830 * Fvid2_queue
831 * \brief An application calls Fvid2_queue to submit a video buffer to the
832 * video device driver.
833 * This is used in capture/display drivers.
834 */
835 int32_t Fvid2_queue(Fvid2_Handle handle,
836 Fvid2_FrameList *frameList,
837 uint32_t streamId)
838 {
839 int32_t retVal = FVID2_SOK;
840 Fdm_Channel *channel;
842 if (NULL != handle)
843 {
844 channel = (Fdm_Channel *) handle;
846 /* Check for NULL pointers */
847 OSAL_Assert(NULL == channel->drv);
848 OSAL_Assert(NULL == channel->drv->drvOps);
850 if (NULL != channel->drv->drvOps->queueFxn)
851 {
852 /* Call the driver's queue function */
853 retVal = channel->drv->drvOps->queueFxn(
854 channel->drvHandle,
855 frameList,
856 streamId);
857 }
858 else
859 {
860 Fvid2_printf("Driver Ops not supported!!\r\n");
861 retVal = FVID2_EUNSUPPORTED_OPS;
862 }
863 }
864 else
865 {
866 Fvid2_printf("EBADARGS: NULL pointer!!\r\n");
867 retVal = FVID2_EBADARGS;
868 }
870 return (retVal);
871 }
873 /**
874 * Fvid2_dequeue
875 * \brief An application calls Fvid2_dequeue to request the video device
876 * driver to give ownership of a video buffer.
877 * This is used in capture/display drivers.
878 */
879 int32_t Fvid2_dequeue(Fvid2_Handle handle,
880 Fvid2_FrameList *frameList,
881 uint32_t streamId,
882 uint32_t timeout)
883 {
884 int32_t retVal = FVID2_SOK;
885 Fdm_Channel *channel;
887 if (NULL != handle)
888 {
889 channel = (Fdm_Channel *) handle;
891 /* Check for NULL pointers */
892 OSAL_Assert(NULL == channel->drv);
893 OSAL_Assert(NULL == channel->drv->drvOps);
895 if (NULL != channel->drv->drvOps->dequeueFxn)
896 {
897 /* Call the driver's dequeue function */
898 retVal = channel->drv->drvOps->dequeueFxn(
899 channel->drvHandle,
900 frameList,
901 streamId,
902 timeout);
903 }
904 else
905 {
906 Fvid2_printf("Driver Ops not supported!!\r\n");
907 retVal = FVID2_EUNSUPPORTED_OPS;
908 }
909 }
910 else
911 {
912 Fvid2_printf("EBADARGS: NULL pointer!!\r\n");
913 retVal = FVID2_EBADARGS;
914 }
916 return (retVal);
917 }
919 /**
920 * Fvid2_processRequest
921 * \brief An application calls Fvid2_processRequest to submit a video buffer
922 * to the video device driver.
923 */
924 int32_t Fvid2_processRequest(Fvid2_Handle handle,
925 Fvid2_FrameList *inFrameList,
926 Fvid2_FrameList *outFrameList)
927 {
928 int32_t retVal = FVID2_SOK;
929 Fdm_Channel *channel;
931 if (NULL != handle)
932 {
933 channel = (Fdm_Channel *) handle;
935 /* Check for NULL pointers */
936 OSAL_Assert(NULL == channel->drv);
937 OSAL_Assert(NULL == channel->drv->drvOps);
939 if (NULL != channel->drv->drvOps->processRequestFxn)
940 {
941 /* Call the driver's process frame function */
942 retVal = channel->drv->drvOps->processRequestFxn(
943 channel->drvHandle,
944 inFrameList,
945 outFrameList);
946 }
947 else
948 {
949 Fvid2_printf("Driver Ops not supported!!\r\n");
950 retVal = FVID2_EUNSUPPORTED_OPS;
951 }
952 }
953 else
954 {
955 Fvid2_printf("EBADARGS: NULL pointer!!\r\n");
956 retVal = FVID2_EBADARGS;
957 }
959 return (retVal);
960 }
962 /**
963 * Fvid2_getProcessedRequest
964 * \brief An application calls Fvid2_getProcessedRequest to request the video
965 * device driver to give ownership of a video buffer.
966 */
967 int32_t Fvid2_getProcessedRequest(Fvid2_Handle handle,
968 Fvid2_FrameList *inFrameList,
969 Fvid2_FrameList *outFrameList,
970 uint32_t timeout)
971 {
972 int32_t retVal = FVID2_SOK;
973 Fdm_Channel *channel;
975 if (NULL != handle)
976 {
977 channel = (Fdm_Channel *) handle;
979 /* Check for NULL pointers */
980 OSAL_Assert(NULL == channel->drv);
981 OSAL_Assert(NULL == channel->drv->drvOps);
983 if (NULL != channel->drv->drvOps->getProcessedRequestFxn)
984 {
985 /* Call the driver's get process frame function */
986 retVal = channel->drv->drvOps->getProcessedRequestFxn(
987 channel->drvHandle,
988 inFrameList,
989 outFrameList,
990 timeout);
991 }
992 else
993 {
994 Fvid2_printf("Driver Ops not supported!!\r\n");
995 retVal = FVID2_EUNSUPPORTED_OPS;
996 }
997 }
998 else
999 {
1000 Fvid2_printf("EBADARGS: NULL pointer!!\r\n");
1001 retVal = FVID2_EBADARGS;
1002 }
1004 return (retVal);
1005 }
1007 /**
1008 * Fvid2_getModeInfo
1009 * \brief Function to get the information about various FVID2 modes/standards.
1010 */
1011 int32_t Fvid2_getModeInfo(Fvid2_ModeInfo *modeInfo)
1012 {
1013 int32_t retVal = FVID2_SOK;
1014 uint32_t entryCnt;
1015 Fvid2_ModeInfo *matchedEntry = NULL;
1017 if (NULL != modeInfo)
1018 {
1019 for (entryCnt = 0U; entryCnt < FDM_NUM_STD_INFO_ENTRIES; entryCnt++)
1020 {
1021 if (gFdmStdInfoTable[entryCnt].standard == modeInfo->standard)
1022 {
1023 matchedEntry = &gFdmStdInfoTable[entryCnt];
1024 break;
1025 }
1026 }
1028 if (NULL == matchedEntry)
1029 {
1030 Fvid2_printf("Unsupported standard!!\r\n");
1031 retVal = FVID2_EINVALID_PARAMS;
1032 }
1033 else
1034 {
1035 Fvid2Utils_memcpy(modeInfo, matchedEntry, sizeof (Fvid2_ModeInfo));
1036 }
1037 }
1038 else
1039 {
1040 Fvid2_printf("EBADARGS: NULL pointer!!\r\n");
1041 retVal = FVID2_EBADARGS;
1042 }
1044 return (retVal);
1045 }
1047 /**
1048 * \brief Function to get the name of the data format in printable string.
1049 *
1050 * \param dataFmt [IN] Data format to get the name.
1051 * For valid values see #Fvid2_DataFormat.
1052 *
1053 * \return Returns a const pointer to the string. If the data format is not
1054 * known, then it return the string as "UNKNOWN".
1055 */
1056 const char *Fvid2_getDataFmtString(uint32_t dataFmt)
1057 {
1058 uint32_t entryCnt;
1059 const char *dataFmtStr = NULL;
1061 for (entryCnt = 0U; entryCnt < FDM_NUM_DATA_FMT_STR_ENTRIES; entryCnt++)
1062 {
1063 if (gFdmDataFmtStrTable[entryCnt].dataFmt == dataFmt)
1064 {
1065 dataFmtStr = gFdmDataFmtStrTable[entryCnt].dataFmtStr;
1066 break;
1067 }
1068 }
1070 if (NULL == dataFmtStr)
1071 {
1072 dataFmtStr = "UNKNOWN";
1073 }
1075 return (dataFmtStr);
1076 }
1078 /**
1079 * \brief Function to get the name of the standard in printable string.
1080 *
1081 * \param standard [IN] Standard to get the name.
1082 * For valid values see #Fvid2_Standard.
1083 *
1084 * \return Returns a const pointer to the string. If the standard is not
1085 * known, then it return the string as "UNKNOWN".
1086 */
1087 const char *Fvid2_getStandardString(uint32_t standard)
1088 {
1089 uint32_t entryCnt;
1090 const char *stdStr = NULL;
1092 for (entryCnt = 0U; entryCnt < FDM_NUM_STD_STR_ENTRIES; entryCnt++)
1093 {
1094 if (gFdmStdStrTable[entryCnt].standard == standard)
1095 {
1096 stdStr = gFdmStdStrTable[entryCnt].stdStr;
1097 break;
1098 }
1099 }
1101 if (NULL == stdStr)
1102 {
1103 stdStr = "UNKNOWN";
1104 }
1106 return (stdStr);
1107 }
1109 /**
1110 * Fvid2_checkFrameList
1111 * \brief Checks the FVID2 frame list for error and returns appropriate error.
1112 * This is used by the drivers and not by the application.
1113 */
1114 int32_t Fvid2_checkFrameList(const Fvid2_FrameList *frameList,
1115 uint32_t maxFrames)
1116 {
1117 int32_t retVal = FVID2_SOK;
1118 uint32_t frmCnt;
1120 /* Check for NULL pointer */
1121 if (NULL == frameList)
1122 {
1123 Fvid2_printf("EBADARGS: NULL pointer!!\r\n");
1124 retVal = FVID2_EBADARGS;
1125 }
1126 else
1127 {
1128 /* Check whether num frames is within range */
1129 if (frameList->numFrames > maxFrames)
1130 {
1131 Fvid2_printf("Number of frames exceeds max!!\r\n");
1132 retVal = FVID2_EOUT_OF_RANGE;
1133 }
1135 /* Check whether num frames is within range */
1136 if (frameList->numFrames > FVID2_MAX_FRAME_PTR)
1137 {
1138 Fvid2_printf("Number of frames exceeds FVID2 max!!\r\n");
1139 retVal = FVID2_EOUT_OF_RANGE;
1140 }
1142 /* Check whether num frames is zero */
1143 if (0U == frameList->numFrames)
1144 {
1145 Fvid2_printf("Number of frames is zero!!\r\n");
1146 retVal = FVID2_EOUT_OF_RANGE;
1147 }
1149 if (FVID2_SOK == retVal)
1150 {
1151 /* Check the individual frame pointers */
1152 for (frmCnt = 0U; frmCnt < frameList->numFrames; frmCnt++)
1153 {
1154 /* Check for NULL pointer */
1155 if (NULL == frameList->frames[frmCnt])
1156 {
1157 Fvid2_printf("EBADARGS: NULL pointer!!\r\n");
1158 retVal = FVID2_EBADARGS;
1159 break;
1160 }
1161 }
1162 }
1163 }
1165 return (retVal);
1166 }
1168 /**
1169 * Fvid2_checkDqFrameList
1170 * \brief Checks the FVID2 frame list of dequeue call for error and returns
1171 * appropriate error. For dequeue operation, the frame pointers in the frames
1172 * should not be checked as this will be filled by the driver.
1173 * This is used by the drivers and not by the application.
1174 */
1175 int32_t Fvid2_checkDqFrameList(const Fvid2_FrameList *frameList,
1176 uint32_t maxFrames)
1177 {
1178 int32_t retVal = FVID2_SOK;
1180 /* Check for NULL pointer */
1181 if (NULL == frameList)
1182 {
1183 Fvid2_printf("EBADARGS: NULL pointer!!\r\n");
1184 retVal = FVID2_EBADARGS;
1185 }
1186 else
1187 {
1188 /* Check whether max frames is within range */
1189 if (maxFrames > FVID2_MAX_FRAME_PTR)
1190 {
1191 Fvid2_printf("Number of frames exceeds FVID2 max!!\r\n");
1192 retVal = FVID2_EOUT_OF_RANGE;
1193 }
1194 }
1196 return (retVal);
1197 }
1199 /**
1200 * Fvid2_copyFrameList
1201 * \brief Copies the source frame list to the destination frame list.
1202 * This also resets the frame pointers from the source frame list.
1203 * This is used by the drivers and not by the application.
1204 */
1205 void Fvid2_copyFrameList(Fvid2_FrameList *dest, Fvid2_FrameList *src)
1206 {
1207 uint32_t frmCnt;
1209 /* Check for NULL pointers */
1210 OSAL_Assert(NULL == dest);
1211 OSAL_Assert(NULL == src);
1212 OSAL_Assert(src->numFrames >= FVID2_MAX_FRAME_PTR);
1214 dest->numFrames = src->numFrames;
1215 dest->drvData = src->drvData;
1217 /* Copy the individual frames */
1218 for (frmCnt = 0U; frmCnt < src->numFrames; frmCnt++)
1219 {
1220 dest->frames[frmCnt] = src->frames[frmCnt];
1221 src->frames[frmCnt] = NULL;
1222 }
1224 return;
1225 }
1227 /**
1228 * Fvid2_duplicateFrameList
1229 * \brief Duplicate the source frame list to the destination frame list.
1230 * This does not reset the frame pointers from the source frame list.
1231 * This is used by the drivers and not by the application.
1232 */
1233 void Fvid2_duplicateFrameList(Fvid2_FrameList *dest, const Fvid2_FrameList *src)
1234 {
1235 uint32_t frmCnt;
1237 /* Check for NULL pointers */
1238 OSAL_Assert(NULL == dest);
1239 OSAL_Assert(NULL == src);
1240 OSAL_Assert(src->numFrames >= FVID2_MAX_FRAME_PTR);
1242 dest->numFrames = src->numFrames;
1243 dest->drvData = src->drvData;
1245 /* Duplicate the individual frames */
1246 for (frmCnt = 0U; frmCnt < src->numFrames; frmCnt++)
1247 {
1248 dest->frames[frmCnt] = src->frames[frmCnt];
1249 }
1251 return;
1252 }
1254 /**
1255 * fdmDriverCbFxn
1256 * \brief FVID2 driver manager driver callback function. Whenever the drivers
1257 * wants to call the application callback function, this function will be
1258 * called by the driver and FDM will in turn call the application callback
1259 * function.
1260 * This is used by the drivers and not by the application.
1261 */
1262 static int32_t fdmDriverCbFxn(void *fdmData)
1263 {
1264 int32_t retVal;
1265 Fdm_Channel *channel;
1267 /* Check for NULL pointers */
1268 OSAL_Assert(NULL == fdmData);
1270 channel = (Fdm_Channel *) fdmData;
1271 OSAL_Assert(NULL == channel->cbParams.cbFxn);
1272 retVal = channel->cbParams.cbFxn(channel, channel->cbParams.appData);
1274 return (retVal);
1275 }
1277 /**
1278 * fdmDriverErrCbFxn
1279 * \brief FVID2 driver manager driver error callback function.
1280 * Whenever the drivers wants to call the application error callback function,
1281 * this function will be called by the driver and FDM will in turn call the
1282 * application error callback function.
1283 * This is used by the drivers and not by the application.
1284 */
1285 static int32_t fdmDriverErrCbFxn(void *fdmData, void *errList)
1286 {
1287 int32_t retVal;
1288 Fdm_Channel *channel;
1290 /* Check for NULL pointers */
1291 OSAL_Assert(NULL == fdmData);
1293 channel = (Fdm_Channel *) fdmData;
1294 OSAL_Assert(NULL == channel->cbParams.errCbFxn);
1295 retVal =
1296 channel->cbParams.errCbFxn(channel, channel->cbParams.appData, errList);
1298 return (retVal);
1299 }
1301 /**
1302 * fdmAllocDriverObject
1303 * \brief Allocate memory for driver object from static memory pool.
1304 * Returns NULL if memory pool is full.
1305 */
1306 static Fdm_Driver *fdmAllocDriverObject(void)
1307 {
1308 uint32_t cnt;
1309 Fdm_Driver *drv = NULL;
1311 /* Get a free driver object */
1312 for (cnt = 0u; cnt < FVID2_CFG_FDM_NUM_DRV_OBJS; cnt++)
1313 {
1314 if (FALSE == gFdmObj.fdmDriverObjects[cnt].isUsed)
1315 {
1316 drv = &gFdmObj.fdmDriverObjects[cnt];
1317 drv->isUsed = (uint32_t) TRUE;
1318 break;
1319 }
1320 }
1322 return (drv);
1323 }
1325 /**
1326 * fdmFreeDriverObject
1327 * \brief Free-up the memory allocated for driver object.
1328 */
1329 static int32_t fdmFreeDriverObject(const Fvid2_DrvOps *drvOps)
1330 {
1331 uint32_t cnt;
1332 int32_t retVal = FVID2_EFAIL;
1334 /* Check for NULL pointers */
1335 OSAL_Assert(NULL == drvOps);
1337 /* Free the driver object */
1338 for (cnt = 0u; cnt < FVID2_CFG_FDM_NUM_DRV_OBJS; cnt++)
1339 {
1340 if ((TRUE == gFdmObj.fdmDriverObjects[cnt].isUsed) &&
1341 (drvOps == gFdmObj.fdmDriverObjects[cnt].drvOps))
1342 {
1343 if (0u == gFdmObj.fdmDriverObjects[cnt].numOpens)
1344 {
1345 gFdmObj.fdmDriverObjects[cnt].isUsed = (uint32_t) FALSE;
1346 gFdmObj.fdmDriverObjects[cnt].drvOps = NULL;
1347 gFdmObj.fdmDriverObjects[cnt].numOpens = 0u;
1348 retVal = FVID2_SOK;
1349 }
1350 else
1351 {
1352 Fvid2_printf("Driver in use!!\r\n");
1353 retVal = FVID2_EDEVICE_INUSE;
1354 }
1355 break;
1356 }
1357 }
1359 if (FVID2_EFAIL == retVal)
1360 {
1361 Fvid2_printf("Driver ops not found!!\r\n");
1362 }
1364 return (retVal);
1365 }
1367 /**
1368 * fdmAllocChannelObject
1369 * \brief Allocate memory for channel object from static memory pool.
1370 * Returns NULL if memory pool is full.
1371 */
1372 static Fdm_Channel *fdmAllocChannelObject(void)
1373 {
1374 uint32_t cnt;
1375 Fdm_Channel *channel = NULL;
1377 /* Get a free channel object */
1378 for (cnt = 0u; cnt < FVID2_CFG_FDM_NUM_CH_OBJS; cnt++)
1379 {
1380 if (FALSE == gFdmObj.fdmChannelObjects[cnt].isUsed)
1381 {
1382 channel = &gFdmObj.fdmChannelObjects[cnt];
1383 channel->isUsed = (uint32_t) TRUE;
1384 break;
1385 }
1386 }
1388 return (channel);
1389 }
1391 /**
1392 * fdmFreeChannelObject
1393 * \brief Free-up the memory allocated for channel object.
1394 */
1395 static int32_t fdmFreeChannelObject(Fdm_Channel *channel)
1396 {
1397 int32_t retVal = FVID2_EALLOC;
1399 /* Check for NULL pointers */
1400 OSAL_Assert(NULL == channel);
1402 /* Free the channel object */
1403 if (TRUE == channel->isUsed)
1404 {
1405 channel->isUsed = (uint32_t) FALSE;
1406 retVal = FVID2_SOK;
1407 }
1408 else
1409 {
1410 Fvid2_printf("Freeing a channel object not in use!!\r\n");
1411 }
1413 return (retVal);
1414 }