1 /*
2 * Copyright 2017, 2020 NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_camera.h"
10 #include "fsl_camera_receiver.h"
11 #include "fsl_csi.h"
12 #include "fsl_csi_camera_adapter.h"
13
14 /*******************************************************************************
15 * Definitions
16 ******************************************************************************/
17
18 /*******************************************************************************
19 * Prototypes
20 ******************************************************************************/
21
22 static status_t CSI_ADAPTER_Init(camera_receiver_handle_t *handle,
23 const camera_config_t *config,
24 camera_receiver_callback_t callback,
25 void *userData);
26
27 static status_t CSI_ADAPTER_Deinit(camera_receiver_handle_t *handle);
28
29 static status_t CSI_ADAPTER_Start(camera_receiver_handle_t *handle);
30
31 static status_t CSI_ADAPTER_Stop(camera_receiver_handle_t *handle);
32
33 static status_t CSI_ADAPTER_SubmitEmptyBuffer(camera_receiver_handle_t *handle, uint32_t buffer);
34
35 static status_t CSI_ADAPTER_GetFullBuffer(camera_receiver_handle_t *handle, uint32_t *buffer);
36
37 static void CSI_ADAPTER_Callback(CSI_Type *base, csi_handle_t *handle, status_t status, void *userData);
38
39 static status_t CSI_ADAPTER_InitExt(camera_receiver_handle_t *handle,
40 const camera_config_t *config,
41 const void *specialConfig,
42 camera_receiver_callback_t callback,
43 void *userData);
44
45 /*******************************************************************************
46 * Variables
47 ******************************************************************************/
48 const camera_receiver_operations_t csi_ops = {.init = CSI_ADAPTER_Init,
49 .deinit = CSI_ADAPTER_Deinit,
50 .start = CSI_ADAPTER_Start,
51 .stop = CSI_ADAPTER_Stop,
52 .submitEmptyBuffer = CSI_ADAPTER_SubmitEmptyBuffer,
53 .getFullBuffer = CSI_ADAPTER_GetFullBuffer,
54 .init_ext = CSI_ADAPTER_InitExt};
55
56 /*******************************************************************************
57 * Code
58 ******************************************************************************/
59
CSI_ADAPTER_Init(camera_receiver_handle_t * handle,const camera_config_t * config,camera_receiver_callback_t callback,void * userData)60 static status_t CSI_ADAPTER_Init(camera_receiver_handle_t *handle,
61 const camera_config_t *config,
62 camera_receiver_callback_t callback,
63 void *userData)
64 {
65 csi_config_t csiConfig;
66
67 csi_resource_t *resource = (csi_resource_t *)(handle->resource);
68 csi_private_data_t *privateData = (csi_private_data_t *)(handle->privateData);
69
70 CSI_GetDefaultConfig(&csiConfig);
71
72 csiConfig.bytesPerPixel = config->bytesPerPixel;
73
74 if (kCAMERA_InterfaceGatedClock == config->interface)
75 {
76 csiConfig.workMode = kCSI_GatedClockMode;
77 }
78 else if (kCAMERA_InterfaceNonGatedClock == config->interface)
79 {
80 csiConfig.workMode = kCSI_NonGatedClockMode;
81 }
82 else if (kCAMERA_InterfaceCCIR656 == config->interface)
83 {
84 csiConfig.workMode = kCSI_CCIR656ProgressiveMode;
85 }
86 else
87 {
88 return kStatus_InvalidArgument;
89 }
90
91 csiConfig.linePitch_Bytes = config->frameBufferLinePitch_Bytes;
92 csiConfig.dataBus = resource->dataBus;
93 csiConfig.useExtVsync = true;
94 csiConfig.height = FSL_VIDEO_EXTRACT_HEIGHT(config->resolution);
95 csiConfig.width = FSL_VIDEO_EXTRACT_WIDTH(config->resolution);
96
97 csiConfig.polarityFlags = 0U;
98 if ((uint32_t)kCAMERA_HrefActiveHigh == (config->controlFlags & (uint32_t)kCAMERA_HrefActiveHigh))
99 {
100 csiConfig.polarityFlags |= (uint32_t)kCSI_HsyncActiveHigh;
101 }
102 if ((uint32_t)kCAMERA_DataLatchOnRisingEdge == (config->controlFlags & (uint32_t)kCAMERA_DataLatchOnRisingEdge))
103 {
104 csiConfig.polarityFlags |= (uint32_t)kCSI_DataLatchOnRisingEdge;
105 }
106 if ((uint32_t)kCAMERA_VsyncActiveHigh != (config->controlFlags & (uint32_t)kCAMERA_VsyncActiveHigh))
107 {
108 csiConfig.polarityFlags |= (uint32_t)kCSI_VsyncActiveLow;
109 }
110
111 (void)CSI_Init(resource->csiBase, &csiConfig);
112
113 privateData->callback = callback;
114 privateData->userData = userData;
115
116 return CSI_TransferCreateHandle(resource->csiBase, &(privateData->csiHandle), CSI_ADAPTER_Callback,
117 (void *)(handle));
118 }
119
CSI_ADAPTER_Deinit(camera_receiver_handle_t * handle)120 static status_t CSI_ADAPTER_Deinit(camera_receiver_handle_t *handle)
121 {
122 CSI_Deinit(((csi_resource_t *)handle->resource)->csiBase);
123
124 return kStatus_Success;
125 }
126
CSI_ADAPTER_Start(camera_receiver_handle_t * handle)127 static status_t CSI_ADAPTER_Start(camera_receiver_handle_t *handle)
128 {
129 return CSI_TransferStart(((csi_resource_t *)handle->resource)->csiBase,
130 &(((csi_private_data_t *)(handle->privateData))->csiHandle));
131 }
132
CSI_ADAPTER_Stop(camera_receiver_handle_t * handle)133 static status_t CSI_ADAPTER_Stop(camera_receiver_handle_t *handle)
134 {
135 return CSI_TransferStop(((csi_resource_t *)handle->resource)->csiBase,
136 &(((csi_private_data_t *)(handle->privateData))->csiHandle));
137 }
138
CSI_ADAPTER_SubmitEmptyBuffer(camera_receiver_handle_t * handle,uint32_t buffer)139 static status_t CSI_ADAPTER_SubmitEmptyBuffer(camera_receiver_handle_t *handle, uint32_t buffer)
140 {
141 return CSI_TransferSubmitEmptyBuffer(((csi_resource_t *)handle->resource)->csiBase,
142 &(((csi_private_data_t *)(handle->privateData))->csiHandle), buffer);
143 }
144
CSI_ADAPTER_GetFullBuffer(camera_receiver_handle_t * handle,uint32_t * buffer)145 static status_t CSI_ADAPTER_GetFullBuffer(camera_receiver_handle_t *handle, uint32_t *buffer)
146 {
147 return CSI_TransferGetFullBuffer(((csi_resource_t *)handle->resource)->csiBase,
148 &(((csi_private_data_t *)(handle->privateData))->csiHandle), buffer);
149 }
150
CSI_ADAPTER_Callback(CSI_Type * base,csi_handle_t * handle,status_t status,void * userData)151 static void CSI_ADAPTER_Callback(CSI_Type *base, csi_handle_t *handle, status_t status, void *userData)
152 {
153 camera_receiver_handle_t *cameraReceiverHandle = (camera_receiver_handle_t *)userData;
154 csi_private_data_t *privateData = (csi_private_data_t *)(cameraReceiverHandle->privateData);
155
156 if (NULL != privateData->callback)
157 {
158 if (kStatus_CSI_FrameDone == status)
159 {
160 status = kStatus_Success;
161 }
162 else
163 {
164 status = kStatus_Fail;
165 }
166 privateData->callback(cameraReceiverHandle, status, privateData->userData);
167 }
168 }
169
CSI_ADAPTER_InitExt(camera_receiver_handle_t * handle,const camera_config_t * config,const void * specialConfig,camera_receiver_callback_t callback,void * userData)170 static status_t CSI_ADAPTER_InitExt(camera_receiver_handle_t *handle,
171 const camera_config_t *config,
172 const void *specialConfig,
173 camera_receiver_callback_t callback,
174 void *userData)
175 {
176 return CSI_ADAPTER_Init(handle, config, callback, userData);
177 }
178